【问题标题】:GCC: Alignment settings with __attribute__ and #pragmaGCC:使用 __attribute__ 和 #pragma 的对齐设置
【发布时间】:2017-03-31 07:51:55
【问题描述】:

如何将#pragma pack(2) 定义为结构属性?

我读过here__attribute__((packed,aligned(4)))大致相当于#pragma pack(4)

但是,如果我尝试使用它(至少使用 2 而不是 4),我会得到不同的结果。示例:

#include <stdio.h>

#pragma pack(push, 2)
struct test1 {
    char a;
    int b;
    short c;
    short d;
};
struct test1 t1;
#pragma pack(pop)

struct test2 {
    char a;
    int b;
    short c;
    short d;
} __attribute__((packed,aligned(2)));
struct test2 t2;


#define test(s,m) printf(#s"::"#m" @ 0x%04x\n", (unsigned int ((char*)&(s.m) - (char*)&(s)))
#define structtest(s) printf("sizeof("#s")=%lu\n", (unsigned long)(sizeof(s)))

int main(int argc, char **argv) {
    structtest(t1);
    test(t1,a);
    test(t1,b);
    test(t1,c);
    test(t1,d);

    structtest(t2);
    test(t2,a);
    test(t2,b);
    test(t2,c);
    test(t2,d);
}

输出是(在 x86 或 x86x64、Linux、gcc 4.8.4 上编译):

sizeof(t1)=10
t1::a @ 0x0000
t1::b @ 0x0002
t1::c @ 0x0006
t1::d @ 0x0008
sizeof(t2)=10
t2::a @ 0x0000
t2::b @ 0x0001
t2::c @ 0x0005
t2::d @ 0x0007

成员b、c、d的地址在两种情况下都不相同。

还有其他__attribute__ 我必须添加吗?我什至在 gcc 文档中都找不到关于这些属性的详细文档。

【问题讨论】:

  • 虽然您的偏移量计算看起来不错,但您为什么不使用标准的offsetof 宏?
  • 还要注意size_tsizeof 给你的)正确的格式前缀修饰符是"z"。因此,如果您想打印size_t,您应该使用例如"%zu".
  • 请注意,您的宏似乎重新发明了轮子。有 offsetofsize_t 的格式是 %zu 自 C99 以来。
  • Visual Studio 8 不支持offsetof%zu(我的代码必须在其上编译:-()
  • 因为您希望结构的每个成员在偶数地址上对齐(这是 #pragma pack(2) 所做的),将 __attribute__((__aligned__ (2))) 添加到结构的每个成员 -- char a __attribute__((__aligned__ (2))); 等等在 -- 上,并为整个结构保留__attribute__((__packed__, __aligned__ (2)))

标签: c gcc packing


【解决方案1】:

正如 @Nominal Animal 在 cmets 中所指出的,解决方案是将 __attribute__((__aligned__(s))) 添加到每个结构成员中,因为它可用于为每个成员单独设置对齐方式。

【讨论】:

    猜你喜欢
    • 2012-01-24
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2013-08-31
    • 1970-01-01
    相关资源
    最近更新 更多