当我们使用检查函数的大小时sizeof()
,我们总是得到1个字节。这1个字节表示什么?
Answers:
这是一个约束违例,您的编译器应该对其进行诊断。如果仍然进行编译,则您的程序具有未定义的行为[感谢@Steve Jessop阐明了故障模式,有关某些编译器为何允许这样做的信息,请参见@Michael Burr的回答]:从C11,6.5.3.4./ 1:
的
sizeof
操作者不得应用于具有功能类型的表达式
-std=c11
,也没有 gnu11
。这是一个非常奇怪的编译器扩展。
sizeof(void)
在GNU C.为1
-std=c11
:有人应该将-std=c*
选项参考广告标准。他们不启用一致性模式,只是禁用了扩展,以防止格式正确的程序编译(例如,typeof
作为关键字,因为格式良好的C程序可以将其用作变量名,但是gcc
默认情况下会拒绝该扩展名))。要另外禁用允许格式错误的程序通过未经诊断的扩展,您需要-pedantic
或-pedantic-errors
。
这不是未定义的行为-C语言标准在将sizeof
运算符与功能指示符(函数名称)一起使用时需要进行诊断,因为这对sizeof
运算符是一种约束。
但是,作为C语言的扩展,GCC允许对void
指针和函数指针进行算术运算,这是通过将avoid
或函数的大小视为来完成的1
。因此,该sizeof
运营商将评估到1
的void
或与海湾合作委员会的功能。参见http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
sizeof
通过使用GCC的-pedantic
或-Wpointer-arith
选项,可以使GCC在与这些操作数一起使用时发出警告。或将设为错误-Werror=pointer-arith
。
sizeof
功能不是UB之外,我实际上并未说明任何其他有关UB的信息(我之所以提到它,只是因为其他答案都说它是UB)。但是也许由于我构造句子的方式而使我感到困惑。更加清楚。sizeof
一个功能不是UB(正如一些答案所声称的)。这是违反约束的。因此,它需要诊断。GCC允许它作为扩展。
它表示编译器作者将值定为1,而不是让恶魔从你的鼻子上飞出来(实际上,这是另一种未定义的用法,sizeof
它使我们获得了这样的表达:“ C编译器本身必须发出诊断信息,如果这是第一个要求,程序产生的诊断信息,然后它本身可能导致恶魔从您的鼻子上飞走(顺便说一句,它很可能是记录在案的诊断消息),就像它可能针对进一步违反语法规则或约束(或,因此,无论出于何种原因,它都会选择)。“ https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
因此,there语是“鼻恶魔”,是指编译器为响应未定义的构造而决定执行的操作。1
是这种情况下此编译器的鼻恶魔。
正如其他人指出的那样,sizeof()可以采用任何有效的标识符,但是它不会为函数名称返回有效的结果(说实话是正确的)。此外,它肯定会或可能不会导致“恶魔出鼻”综合症。
如果要分析程序功能的大小,请检查链接器映射,该链接器映射可在中间结果目录中找到(该目录将内容编译为.obj / .o或生成的图像/可执行文件所在的目录)。有时,有一个选项可以生成或不生成此映射文件……它取决于编译器/链接器。
如果您想要函数的指针大小,则它们的大小都是相同的,即cpu上寻址字的大小。
int x = 1;
但是对于符合标准的编译器,只允许其中之一。随着sizeof()
被应用到的功能,它可能会或可能不会返回设定值,或拒绝编译,或者返回基于在当时特定的寄存器无论是一个随机值。文字上的鼻恶魔是不太可能的,但是在标准之内。
sizeof
指针。
-pedantic
),则说明您的编译器不合格,每个程序都有未定义的行为。