【问题标题】:Calculate an arbitrary type's size without executing a program在不执行程序的情况下计算任意类型的大小
【发布时间】:2016-10-10 14:34:27
【问题描述】:

给定 C 程序中的任何类型,我想知道它的大小,例如在执行以下行时,

printf("%d\n",sizeof(myType));

没有实际执行程序。该解决方案必须适用于大小可以在编译时确定的任意类型,例如用户定义的结构。

基本原理是,如果可以在编译时知道它,那么应该有一种方法可以提取该信息而无需运行程序。可能比解析生成的汇编源代码或二进制文件以获得文字常量更优雅一些,但如果这是唯一的方法,我会尽我所能。

This question 不太适合我,因为 OP 的解决方案依赖于执行代码,而投票最多的答案依赖于实际扩展宏的预处理器信息指令(我的工具链显然没有)。

作为背景,我正在为 PIC18 MCU 开发并使用 XC8 编译器。

【问题讨论】:

  • 看看生成的汇编代码?否则,只需阅读 ABI 并自己收集信息。听起来像一个XY问题。你真正想要达到什么目的?你为什么要这样做? 什么你想要这个?
  • 您可以为此使用Compile Time Assertion。非常方便。
  • 正确的方法是静态断言。或者只是不依赖于此,而是编写正确的代码,其余的留给编译器。
  • @EugeneSh.:如果有标准版本,请不要直接指向非标准拼凑。见_Static_assert
  • @Olaf 并非每个编译器都遵循最新标准,而且您知道...

标签: c types compilation sizeof


【解决方案1】:

我最终想要的是验证我定义的某些结构是否占用了它们在内存中的预期大小。

这是静态断言的经典用例。如果你的编译器支持_Static_assert,你可以写

_Static_assert(sizeof(mystruct) == expected_size, "Invalid struct size.");

demo 1

如果您使用尚不支持 C-1x 的旧编译器,请使用依赖于声明具有负大小的数组类型的常见解决方法:

#define CHECK_SIZE(x,e) if(sizeof(char[2*(sizeof(x)==e)-1])==1);

demo 2

【讨论】:

  • >If you use an older compiler that does not support C-1x yet, use a common work-around that relies on declaring an array type with negative size 谢谢!我认为这可能会奏效,所以我尝试了一下。不幸的是,我的编译器不配合,很乐意编译您的 demo2 代码(考虑了类型大小的差异)。它也会做诸如struct s { int8_t a; };typedef char pass_assertion[ sizeof(struct s) == 20 ]; //I understand this should yield the null byte之类的事情,同时它会拒绝typedef char fail_assertion[ 0 ]
  • @DanielArmengod 括号中的表达式旨在当表达式为假时变为负数。编译器将采用大小为零的数组,但它们必须拒绝负大小的数组。要在您的编译器上尝试此操作,请创建一个 typedef char foo[-1]; 并查看您的编译器的反应。
  • 我的编译器拒绝接受维数为 0 的数组。它会生成以下错误消息:newmain.c:3: error: (284) invalid dimension (tested with typedef char a[0])
  • @DanielArmengod 如果你在没有if(即#define CHECK_SIZE(x,e) typedef char size_check[2*(sizeof(x)==e)-1])的情况下编写相同的代码会发生什么?
  • 最后一个建议有效!谢谢!我真的不明白为什么它在 if 条件下不起作用。我做了一些测试,发现如果被测试的变量具有基本类型(例如 char、long),它将正常工作,但是如果它是struct X 类型,那么无论该结构是什么以及您正在检查的大小是什么反对,它永远不会触发。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
相关资源
最近更新 更多