error C2143 error C2059
-
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));
}// and you would then call it by something like:
static int some_function(const geometry_t* geometry)
{
// assuming that part_type is an offset rather than a pointer
if (struct_cmp(&geometry->part_type, &GEOM_TYPE_X) == 0)
return 1;return 0;
}
Perhaps you could show the definition of the geometry opbject?
-
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));
}// and you would then call it by something like:
static int some_function(const geometry_t* geometry)
{
// assuming that part_type is an offset rather than a pointer
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 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; };
-
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));
}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.
-
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.
-
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.
-
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
. -
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
-
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
-
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 ) { // this is not the preferred method for comparing floating-point values (but that's not the point) 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
-
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 !
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 asmemcmp(str1, str2, sizeof str1)
. You could, usememcmp(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. Usestrcmp()
to compare strings, orstrcasecmp()
orstrcoll()
when appropriate. -
_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 ) { // this is not the preferred method for comparing floating-point values (but that's not the point) 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
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 int main()
{
double d = 0.0;
const double one = 1.0;for(size\_t i = 0; i < 100; ++i) d += 0.01; // we would expect d now to be 1.0, but ... printf("d = %8.6f\\n", d); // output looks like 1.000000 printf("d == 1.0 => %d\\n", d == one); // but comparison fails printf("1.0 - d = %g\\n", one -d); // there's a very small diff btwn d and 1.0 return 0;
}
$ ./ex
d = 1.000000
d == 1.0 => 0
1.0 - d = -6.66134e-16
$