GCC проблема неявного выравнивания.(64-битный код) - PullRequest
2 голосов
/ 03 февраля 2011

Как я могу явно отключить выравнивание по определенной переменной в gcc?
Взять этот код:

typedef struct{
  unsigned long long offset;
  unsigned long long size;
  unsigned long type;
  unsigned long acpi;
}memstruct;

memstruct *memstrx;

Это определит структуру размером 24 байта.
Я попытался сделать:

memstrx=(void*)(0x502);

То есть

&memstrx[0] должно иметь значение 0x502
&memstrx[1], 0x51A
&memstrx[2], 0x532

...и т. д. и т. п.

Но, похоже, все не так.

Вместо этого

&memstrx[1] отображает адрес 0x522
&memstrx[2], 0x542
&memstrx[3], 0x552

... и т. Д. И т. П.

Я подозреваю, что GCC неявно изменил размер структуры до 32байты (от 24 байтов), форсируя (64-битное выравнивание каждой записи).И я действительно не хочу такого поведения только для этой структуры.Как я должен сказать GCC не выравнивать эту структуру?

Ответы [ 3 ]

6 голосов
/ 03 февраля 2011

Нет, это невозможно сделать.

Минимальный размер отображаемой структуры составляет 8 * 4 = 32 байта.

sizeof (unsigned long) = 8 в 64-битной архитектуре(Linux)

Редактировать: , если бы вы использовали

- unsigned вместо unsigned long

или

  • uint32_t и uint64_t вместо unsigned long и unsigned long long

вы получите ожидаемое выравнивание.

2 голосов
/ 03 февраля 2011

# pragma pack (x) может изменить ограничения выравнивания структуры как в GCC, так и в MSVC.

GCC использует модель LP64 для 64-битных сборок - это означает, что длинные и указатели являются 64-битными. Вам нужно перейти на unsigned int для ваших 32-битных полей, ИЛИ использовать uint32_t и uint64_t для стабильных размеров полей.

#pragma pack(1)

typedef struct{
  unsigned long long offset;
  unsigned long long size;
  unsigned int type;
  unsigned int acpi;
}memstruct;

#pragma pack()
1 голос
/ 03 февраля 2011

вот один из вариантов управления выравниванием с помощью gcc:

http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

...