Я пишу кроссплатформенную библиотеку C, но в итоге у меня возникла ошибка в моих тестах юнитов, но только на компьютерах с Windows. Я отследил проблему и обнаружил, что она связана с выравниванием структур (я использую массивы структур для хранения данных для нескольких похожих объектов). Проблема заключается в следующем: memset (sizeof (struct)) и установка элементов структуры один за другим приводят к разным байтовым результатам, и поэтому memcmp () возвращает результат «не равно».
Вот код для иллюстрации:
#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;
}
Этот код с MSVC 2003 @ Windows производит следующий вывод:
16 8
Not equal
Но тот же код с GCC 3.3.6 @ Linux работает как положено:
12 8
Equal
Это делает мои юнит-тесты очень сложными.
Правильно ли я понимаю, что MSVC использует размер самого большого собственного типа (long long) для определения выравнивания по структуре?
Может ли кто-нибудь дать мне совет, как я могу изменить свой код, чтобы сделать его более устойчивым к этой странной проблеме выравнивания? В моем реальном коде я работаю с массивами структур через общие указатели для выполнения memset / memcmp, и я обычно не знаю точного типа, у меня есть только значение sizeof (struct).