|
That is not a struct or a union. Is there some other code that you need to show us?
|
|
|
|
|
The original code is:
typedef struct {
....
....
char* file_name[0];
};
also, I get another warning here:
warning C4094: untagged 'struct' declared no symbols
I don't know how to get rid of this warnings ...
|
|
|
|
|
You are using a typedef but have not given it the name that you wish to use. It should be something like:
typedef struct {
....
....
char* file_name[0];
} myStruct;
Also the comment on the last line makes no sense; firstly it is declaring an aray of pointers rather than characters. And secondly, you should not store Unicode characters in a char type array. It will most likely cause problems at run time.
The zero length array is possibly valid, but it depends on how the code uses the struct. It can be used as a placeholder name for space that will be allocated for a dynamic structure at run time. Something like:
struct foo
{
int i;
char text[0];
};
struct foo* myFoo = (struct foo*)malloc(sizeof(struct foo) + 20);
|
|
|
|
|
I was about to write an answer when i saw this. Yes, zero length char arrays at the end of a struct appeared to be quite common in C programming some years (or decades, rather) ago. I haven't seen it in any C++ code ever, although it probably works the same. Whatever you wish to achieve, there's probably a better solution available in C++ syntax. Usually, std::string is the go to solution here.
That said, yes, it must be char [] , not char* [] , otherwise it doesn't make any sense at all.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Stefan_Lang wrote: it doesn't make any sense at all. Sadly true of so much that we see here.
|
|
|
|
|
pretty sure you could just use char* name;
since the array size is 0.
|
|
|
|
|
Read carefully the documentation[^] (see the sample code).
Using _MAX_PATH (or whatever >0 ) is correct, the impact is in memory: each time the struct is allocated, _MAX_PATH character pointers are allocated too. You might instead choose to disable the warning, if it makes sense (e.g. there is an additional field in the struct specifying the actual size of the array).
|
|
|
|
|
I guess disabling this warning is best solution … how can I do that ? With pragma statement ? If yes, which version of pragma should I use ?
|
|
|
|
|
Never disable warnings, they are there to help you.
|
|
|
|
|
Don't disable warnings unless you are 100% sure what they're telling you, 100% sure that this is not a problem for the syntactic and semantic functionality of your code, and at least 90% sure there's no reasonable way to avoid them.
Under these conditions, the best way is to use #pragma push immediately before the disable command and #pragma pop after the code that causes the warning. That way you can be sure that the remainder of the code will use the same warning settings as defined in the compiler options.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Sorry, I didn't saw the link first time ...
modified 6-Aug-19 5:21am.
|
|
|
|
|
I am trying to integrate some old C code in a C++/MFC project and I met a strange error:
error C2143: syntax error : missing ')' before '{'
error C2059: syntax error : ')'
error C2143: syntax error : missing ')' before '{'
error C2143: syntax error : missing ')' before '{'
error C2143: syntax error : missing ';' before '{'
error C2059: syntax error : '{'
error C2059: syntax error : ')'
error C2059: syntax error : ')'
error C2059: syntax error : '=='
error C2059: syntax error : ')'
Here is the code:
static int some_function(const geometry_t* geometry)
{
if (struct_cmp(geometry->part_type, GEOM_TYPE_X) == 0) return 1;
return 0; }
Here is how is defined GEOM_TYPE_X:
#define GEOM_TYPE_X \
((const air_t){0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}})
and air_t is:
typedef struct air_s air_t;
struct air_s
{
unsigned int val1;
unsigned short val2;
unsigned short val3;
unsigned char val4;
unsigned char val5;
unsigned char node[6];
};
geometry->part_type is the same air_t type ... and struct_cmp is:
static inline int struct_cmp(const air_t left, const air_t right)
{
return memcmp(&left, &right, sizeof(air_t));
}
Why I get this errors ? Where I should modify the code to make it run ? I have tried to modify GEOM_TYPE_X in several ways, no one has worked ...
Can you give me a little hint to get rid of this errors ?
P.S. Do you have enough information to see the problem ? If not, tell me to give you more details ...
modified 31-Jul-19 7:23am.
|
|
|
|
|
I am not sure what the problem is, but why are you passing complete structures to your compare function instead of pointers?
|
|
|
|
|
Yes, is thre complete structures, but I guess that is the right way:
static inline int struct_cmp(const air_t left, const air_t right)
{
return memcmp(&left, &right, sizeof(air_t));
}
|
|
|
|
|
No, the right way would be to pass the addresses of the structures to the function. Passing a structure in a function call adds a lot of extra redundant code. So the more correct way would be:
static inline int struct_cmp(const air_t* left, const air_t* right)
{
return memcmp(left, right, sizeof(air_t));
}
static int some_function(const geometry_t* geometry)
{
if (struct_cmp(&geometry->part_type, &GEOM_TYPE_X) == 0)
return 1;
return 0;
}
Perhaps you could show the definition of the geometry opbject?
|
|
|
|
|
I have tried in this way:
if (struct_cmp(&geometry->part_type, &GEOM_TYPE_X) == 0)
no changes.
Here is the geometry object:
typedef struct geometry_struct geometry_t;
struct geometry_struct
{
char name[128];
char info[128];
unsigned long long org_offset;
unsigned long long sb_offset;
unsigned int sb_size;
air_t part_type;
unsigned int geom_type;
status_type_t status;
unsigned int order;
errcode_type_t errcode;
const fnct_t *air;
};
|
|
|
|
|
I get a different error message when I try. However by changing the define of GEOM_TYPE_X to the following, it seems to work:
const air_t GEOM_TYPE_X = {0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}};
And also that is much better than using a #define .
|
|
|
|
|
Thank you so much Richard, seem to go now this issue ... now I have to solve the rest of 1000 errors
|
|
|
|
|
Be careful when using memcmp() to compare structures. Due to alignment issues, you may have padding bytes between members e.g.
struct foo {
short s;
double d;
};
In 64-bit mode, I get 6 bytes of padding between foo.s and foo.d, in 32-bit mode it's 2. This means that memcmp() may not return 0 even when the members are equal.
|
|
|
|
|
Thank you for your notice, I will compile this project on 32 bit, that code is inherited from that old C project … do you suggest me another safe method to compare structs ? A little code sample will be great !
|
|
|
|
|
_Flaviu wrote: do you suggest me another safe method to compare structs ? A little code sample will be great ! How about something akin to:
struct foo
{
short s;
double d;
bool equals( struct foo f )
{
return (this->s == f.s) && (this->d == f.d);
}
};
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
modified 1-Aug-19 10:32am.
|
|
|
|
|
David Crow wrote: bool equals( struct foo f )
{
// this is not the preferred method for comparing floating-point values
return (this->s == f.s) && (this->d == f.d);
}
I use fabs(v1 - v2) < delta . Its OK to compare a floating point value against zero, but other comparisons may produce unexpected results. e.g.
$ cat ex.c
#include <stdio.h>
int main()
{
double d = 0.0;
const double one = 1.0;
for(size_t i = 0; i < 100; ++i)
d += 0.01;
printf("d = %8.6f\n", d);
printf("d == 1.0 => %d\n", d == one);
printf("1.0 - d = %g\n", one -d);
return 0;
}
$ ./ex
d = 1.000000
d == 1.0 => 0
1.0 - d = -6.66134e-16
$
|
|
|
|
|
The only way I know is to compare member by member:
struct foo {
short s;
double d;
char str[24];
};
int compare_foo(const struct foo *f1, const struct foo *f2)
{
int retval;
if( (retval = f1->s - f2->s) != 0)
return retval;
if( (retval = f1->d - f2->d) != 0)
return retval;
return strcmp(f1->str, f2->str);
}
Note that this demonstrates another reason that you should avoid memcmp() on structs: if the struct in question contains strings, the portions of the string after the terminating null byte may not be equal, so strcmp(str1,str2) might not return the same value as memcmp(str1, str2, sizeof str1) . You could, use memcmp(str1, str2, strlen(s1)+1) : the extra byte accounting for the terminating null byte, so that you do not get a false equal on e.g. "help" and "helper". But that's a silly way to compare strings: you effectively run through str1 twice, once to get its length, then again to do the comparison, assuming str1 is equal to, or an initial substring of, str2. Use strcmp() to compare strings, or strcasecmp() or strcoll() when appropriate.
modified 1-Aug-19 10:35am.
|
|
|
|
|
But surely if both structs are in the same build the padding will be the same?
|
|
|
|
|
Sure, the size/alignment will be the same, but the devil is in the padding. It's uninitialised, and quite unlikely to have the same value in the two structs being compared, so memcmp() will fail even though all fields of the structs are identical.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|