为什么C中函数的大小总是1个字节?

use*_*461 87 c size function sizeof

当我们检查函数的大小时sizeof(),我们总是得到1个字节.这个1字节表示什么?

Ker*_* SB 80

这是违反约束的行为,您的编译器应该对其进行诊断.如果它尽管如此编译它,你的程序有不确定的行为[感谢@Steve Jessop澄清失败模式,并参见@Michael Burr的答案,为什么有些编译器允许这样做]:来自C11,6.5.3.4./ 1:

sizeof操作者不得应用于具有功能类型的表达式

  • 这是一个约束,这意味着在一个符合标准的编译器中它被诊断出来.如果编译器无论如何编译它(已经诊断出来),那么行为是不确定的.如果编译器没有对它进行诊断(例如gcc没有`-pedantic`),那么你就有了一个不合格的编译器,并且每个*程序都有未定义的行为. (11认同)
  • 哦!我打赌它是对函数指针进行算术运算,就像GNU C中`sizeof(void)`为1一样. (6认同)
  • 关于`-std = c11`:有人应该将`-std = c*`选项引用到广告标准.它们不启用一致性模式,它们只是禁用会阻止格式良好的程序编译的扩展(例如`typeof`是一个关键字,因为格式良好的C程序可以将它用作变量名,但是`gcc `默认会拒绝这个).要额外禁用允许不正确的程序通过未确诊的扩展,您需要`-pedantic`或`-pedantic-errors`. (3认同)

Mic*_*urr 56

这不是未定义的行为 - 当使用sizeof带有函数指示符(函数名称)的运算符时,C语言标准需要诊断,因为它违反了sizeof运算符.

但是,作为C语言的扩展,GCC允许对void指针和函数指针进行算术运算,这可以通过将a void或函数的大小视为1.因此,该sizeof运营商将评估到1void或与海湾合作委员会的功能.见http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith

sizeof通过使用GCC -pedantic-Wpointer-arith选项,您可以让GCC在使用这些操作数时发出警告.或者使它成为一个错误-Werror=pointer-arith.

  • C要求对所有约束违规进行诊断(5.1.1.3 C99或C11中的诊断).约束(C99/C11中的3.8)是"限制,无论是语法还是语义,通过它来解释语言元素的阐述",这似乎表明不遵循约束的东西不能被解释. (4认同)
  • 并且要明确 - 约束违规不会导致未定义的行为.这是一个错误,就像语法错误一样.例如,标准说,"如果违反"约束**之外的"必须"或"不应"要求**,则行为未定义".如果约束违规会导致UB,那么为什么标准只讨论那些不受限制的"必须"和"不应该"? (3认同)
  • 我真的没有说明UB的任何内容,除了`sizeof`一个函数不是UB(我之前提到的只是因为其他答案说它是UB).但也许我糊涂了,因为我构造句子的方式.更清楚.`sizeof`一个函数不是UB(正如几个答案所声称的那样).这是违反约束的行为.因此,它需要诊断.GCC允许它作为扩展. (3认同)
  • @KerrekSB:OP没有得到诊断,因为他们可能正在使用GCC,这允许将其用作C语言扩展. (2认同)

Jon*_*nna 13

它表示编译器编写器决定值为1而不是让恶魔从你的鼻子中飞出(事实上,这是另一个未定义的用法,sizeof它给了我们这个表达式:"C编译器本身必须发出诊断,如果这是第一个必需的从你的程序产生的诊断,然后MAY本身会导致恶魔从你的鼻子飞过(顺便说一句,很可能是记录的诊断信息),就像它可能会进一步诊断进一步违反语法规则或约束一样(或者,就此而言,无论出于何种原因选择)." https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J

从这里可以得出俚语术语"鼻子恶魔",无论编译器决定如何应对未定义的构造.1对于这种情况,这是这个编译器的鼻恶魔.


jpi*_*912 7

正如其他人所指出的,sizeof()可以获取任何有效的标识符,但它不会返回函数名称的有效(真实且真实且有效)结果.此外,它肯定可能会或可能不会导致"恶魔出鼻"综合症.

如果要分析程序函数大小,请检查链接器映射,该映射可以在中间结果目录(将事物编译为.obj/.o或生成的映像/可执行文件所在的目录)中找到.有时可以生成或不生成此映射文件...它依赖于编译器/链接器.

如果你想要一个函数指针的大小,它们的大小都是相同的,就是cpu上的一个寻址字的大小.