Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Internal consistency of C structures

Tags:

c

struct

memcmp

If I have two C structures initialised to have identical members, can I guarantee that:

memcmp(&struct1, &struct2, sizeof(my_struct))

will always return zero?

like image 489
Sparky Avatar asked May 29 '13 13:05

Sparky


2 Answers

I don't think you can safely memcmp a structure to test for equality.

From C11 §6.2.6.6 Representations of types

When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.

This implies that you'd need to write a function which compares individual elements of the structure

int my_struct_equals(my_struct* s1, my_struct* s2)
{
    if (s1->intval == s2->intval &&
        strcmp(s1->strval, s2->strval) == 0 && 
        s1->binlen == s2->binlen &&
        memcmp(s1->binval, s2->binval, s1->binlen) == 0 &&
        ...
        ) {
        return 1;
    }
    return 0;
}
like image 118
simonc Avatar answered Nov 07 '22 18:11

simonc


No, two structures with all members equal may sometimes not compare equal for memcmp(), because of padding.

One plausible example is as follows. For the initialization of st2, a standard-compliant 32-bit compiler could generate a sequence of assembly instructions that leave part of the final padding uninitialized. This piece of padding will contain whatever happened to be there on the stack, whereas st1's padding will typically contain zero:

struct S { short s1; long long i; short s2; } st1 = { 1, 2, 3 };
int main() {
  struct S st2 = { 1, 2, 3 };
  ... at this point memcmp(&st1, &st2, sizeof(struct S)) could plausibly be nonzero
}
like image 9
Pascal Cuoq Avatar answered Nov 07 '22 19:11

Pascal Cuoq