I am writing a C cross-platform library, but in the end I have an error in my unittests, but only on Windows machines. I tracked the problem and found that it is related to alignment of structures (I use arrays of structures to store data for several similar objects). The problem is that memset (sizeof (struct)) and structural elements in turn produce different byte-byte results, and therefore memcmp () returns a non-equal result.
Here is the code to illustrate:
#include <stdio.h> #include <string.h> typedef struct { long long a; int b; } S1; typedef struct { long a; int b; } S2; S1 s1, s2; int main() { printf("%d %d\n", sizeof(S1), sizeof(S2)); memset(&s1, 0xFF, sizeof(S1)); memset(&s2, 0x00, sizeof(S1)); s1.a = 0LL; s1.b = 0; if (0 == memcmp(&s1, &s2, sizeof(S1))) printf("Equal\n"); else printf("Not equal\n"); return 0; }
This code with MSVC 2003 @Windows produces the following output:
16 8 Not equal
But the same code with GCC 3.3.6 @Linux works as expected:
12 8 Equal
This makes my unit testing very difficult.
Did I understand correctly that MSVC uses the size of the largest native type (long long) to determine the alignment of the structure?
Can someone give me some advice on how I can change my code to make it more resistant to this strange alignment problem? In my real code, I work with arrays of structures through shared pointers to execute memset / memcmp, and I usually don't know the exact type, I only have the value of sizeof (struct).
c struct alignment cross-platform unit-testing
bialix
source share