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

use*_*570 5 c gcc x86-64 padding gcc6

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

struct list {
    ...  
    ...
    const unsigned char nop=0x90; // 27 bytes since the begining of the structure
    const unsigned char jump=0xeb; // 28 bytes since the begining of the structure
    const unsigned char hlt=0xf4; // 29 bytes since the begining of the structure
    unsigned __int128 i=0xeb90eb90eb90eb90f4f4 // should start at the 30th byte, but get aligned on a 16 byte boundary and starts on the 32th byte instead
    const unsigned char data=0x66; // should start at the 46th byte, but start on the 48th instead.
}; // end of struct list.
Run Code Online (Sandbox Code Playgroud)

我很难找出为什么我的程序不能正常工作,但我终于发现它之间存在2个字节的间隙,hlt并且i设置为0x0.这意味着它i正在变得一致.
当我打印那部分结构时,这是非常清楚的,因为:

for(int i=28;i<35;i++)
    printf("%02hhX",buf[i]);
Run Code Online (Sandbox Code Playgroud)

我进入EBF40000EB90EB90了屏幕.

volatile struct list data;在我的程序中尝试过类似的东西,但它没有改变对齐问题.

那么是否有一个#pragma或一个__attribute__告诉gcc不对齐i内部struct list类型?

Ole*_*nov 22

在GCC中你可以__attribute__((packed))像这样使用:

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

// sizeof(y) == 5
struct y
{
    char x;
    int a;
} __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)

文档.

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


inf*_*xed 5

如@Banex所感动

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

#pragma pack(push,1)内部将当前的包装模式,设定包装为1,没有填充

#pragma pack(pop) 恢复以前的包装

据说与微软的语法兼容

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