【发布时间】:2021-09-16 12:54:20
【问题描述】:
给定一个结构,例如:
struct A {
char a;
char b;
} __attribute__((packed));
我希望在编译时打印结构中 b(在本例中为 1)的偏移量 - 我不想运行程序并调用类似 printf("%zu", offsetof(struct A, b)); 的东西,因为打印不是- 在我的平台上微不足道。我希望编译器本身打印偏移量,例如:
> gcc main.c
The offset of b is 1
我尝试了几种使用#pragma message 和offsetof 的方法,最接近的是:
#define OFFSET offsetof(struct A, b)
#define XSTR(x) STR(x)
#define STR(x) #x
#pragma message "Offset: " XSTR(OFFSET)
只打印:
> gcc main.c
main.c:12:9: note: #pragma message: Offset: __builtin_offsetof (struct A, b)
不打印数字偏移量。可以在编译时使用 _Static_assert 对偏移量进行二进制搜索 - 但我的真实结构很大,这可能会有点麻烦。
【问题讨论】:
-
你不能写一个单独的测试程序来打印你需要的值吗?
-
使用 GCC 和 Clang,您可以生成包含偏移量的“程序集”。例如,将
__asm__("# offsetof(struct A, b) = %c0" : : "i" (offsetof(struct A, b)));行放入函数中,编译为程序集(-S开关),生成的程序集将包含## offsetof(struct A, b) = 1之类的行。当然,您可以使用grep从程序集中提取该行。 -
为什么不能只检查链接器映射文件以查看结构最终有多大?
-
@nielsen 你在按钮上 - 我的主要收获是我对编译时消息的有限性感到有点惊讶(特别是考虑到像
_Static_assert这样的功能存在)。不仅要打印偏移量,而且要打印sizeof等其他编译器信息似乎很困难。似乎最好的解决方案实际上是 hacky 解决方案,例如尝试通过编译器警告泄漏信息的答案,或者通过从编译的二进制文件中提取嵌入信息。 -
@hyde 我的具体情况是一些汇编代码需要用寄存器中结构的基地址取消引用结构的成员,我想要一种快速的方法来知道成员的偏移量跨度>