Структурная упаковка в GCC на 32-битной не работает?

Я унаследовал какой-то сторонний код в проекте. Он состоит из заголовочного файла и двоичной библиотеки без исходных текстов, поэтому я не могу просто перекомпилировать его с другими настройками.

Заголовок использует трюк во время компиляцииtypedefиспользование массива отрицательного размера, если выражение не выполнено) для обеспечения правильного выравнивания структуры, но, похоже, оно не работает в 32-битном режиме.

Вот отдельная небольшая программа, которая охватывает всю проблему:

#include <stdio.h>
#include <stddef.h>

#pragma pack(push, 8)
struct test {char _; long long a;};
typedef char pack_test[(offsetof(test, a) == 8) ? 1 : -1];
#pragma pack(pop)

int main(int argc, char *argv[])
{
printf("%d\n", offsetof(test, a));
return 0;
}

Приведенный выше код не компилируется как на clang 3.0, так и на любой недавней версии gcc, на которую я мог быстро наложить руку (4.5 до 4.7): прагмы упаковки просто не имеют никакого эффекта. Компилятор продолжает выравнивать элемент a до 4 байтов (вы можете проверить это, комментируя typedef из).

Это почему? Как я могу исправить код так, чтобы это утверждение не проваливалось и поддерживало его совместимость с ABI, при этом не нужно проходить через все структуры в заголовке и закреплении attributeна их хвосты?

3

Решение

В 32-битной системе long long может не потребоваться выравнивание восьми байтов, четырех должно быть достаточно. В конце концов, вы все равно извлекаете два целых слова из памяти, независимо от того, является ли первое из них выровненным по восьми байтам или четырьмя.

Вы можете попытаться принудительно выровнять восемь байтов с атрибутом

struct test { char _; long long a __attribute__ ((aligned(8))); };

(вероятно, неправильно, я не знаком с атрибутами gcc)

Конечно, вы также можете добавить фиктивного члена к struct чтобы обеспечить желаемое выравнивание

struct test { char _; char dummy[7]; long long a; }

Это должно работать на практике.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]