如何告诉gcc在struct中禁用填充?

时间:2016-11-16 21:34:56

标签: c gcc x86-64 padding gcc6

我不确定它是否正常或者它是编译器错误但是我有一个包含很多成员的C结构。其中包括:

hlt

我很难找到我的程序无效的原因,但我终于发现 ii 之间存在2个字节的差距到0x0。这意味着for(int i=28;i<35;i++) printf("%02hhX",buf[i]); 正在对齐 当我打印结构的那部分时,这是非常清楚的,因为:

EBF40000EB90EB90

我在屏幕上显示volatile struct list data;

我在程序中尝试了#pragma之类的内容,但它没有改变对齐问题。

那么是否有__attribute__i告诉gcc未在struct list类型中对齐resultsAsXml

3 个答案:

答案 0 :(得分:19)

在GCC中,您可以像这样使用__attribute__((packed))

// sizeof(x) == 8
struct x
{
    char x;
    int a;
};

// sizeof(y) == 5
struct y
{
    char x;
    int a;
} __attribute__((packed));

请参阅doc

此外,如果您依赖结构字段的地址,请查看offsetof宏。也许你根本不需要打包结构。

答案 1 :(得分:4)

由@Banex提及

#pragma pack(push,1)
struct
{
        char a;
        int b;
        long long c;
} foo;
#pragma pack(pop)

#pragma pack(push,1)在内部推送当前打包模式,并将打包设置为1,无填充

#pragma pack(pop)恢复之前的打包

据称与Microsoft的语法兼容

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

答案 2 :(得分:2)

struct中的字段以实现定义的方式填充。

话虽这么说,字段通常是在一个offest上对齐的,这个字段是数据成员(或者如果成员是数组的数组元素)的大小的倍数。因此,一个16位字段从2字节偏移开始,32位字段从4字节偏移开始,依此类推。

如果您对struct中的字段重新排序以遵守此指南,通常可以避免在struct中使用任何内部填充(尽管最终可能会出现一些尾随填充)。

通过将字段放在适当的偏移处,可以在强行打包struct时获得性能提升。

有关详细信息,请参阅this article on structure packing

虽然不能保证使用上述技术,但在大多数情况下它们都适用。