sizeof(函数名)返回什么?

示例代码:

main () { printf ("size = %d\n", sizeof (main)); } 

C标准禁止它 – 当使用gcc -pedantic编译时,它invalid application of 'sizeof' to a function type警告产生invalid application of 'sizeof' to a function type

但是gcc编译它并为sizeof(main)返回1 ,它不是函数指针的大小。

它似乎与编译器有关。

sizeof运算符

  sizeof unary-expression sizeof ( type-name ) 

操作数可以是一元表达式的标识符,也可以是类型转换表达式(即括在括号中的类型说明符)。 一元表达式不能表示位字段对象,不完整类型或function designator 。 结果是无符号整数常数。 标准头文件STDDEF.H将此类型定义为size_t

使用编译标志-Wall -pedanticsizeof发出有关错误操作数的警告(记住sizeof是编译时操作符),代码:

 $ cat sizeof.c #include int main(){ printf("%zu %p\n", sizeof(main), (void*)main); return 0; } 

GCC版本4.6.3的编译消息(Ubuntu / Linaro 4.6.3-1ubuntu5):

 $ gcc -Wall -pedantic sizeof.c -std=c99 sizeof.c: In function 'main': sizeof.c:3:30: warning: invalid application of 'sizeof' to a function type [-pedantic] sizeof.c:3:38: warning: ISO C forbids conversion of function pointer to object pointer type [-pedantic] 

阅读:

6.5.3.4 sizeof运算符

1118 – sizeof运算符应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式
1127 – 结果的值是实现定义的,其类型(无符号整数类型)是size_t ,在 (和其他头文件)中定义

另外, size_t正确格式字符串是%zu ,如果它不存在,例如Microsoft的编译器,则可以使用%lu并将返回值转换为unsigned long

ISO C ++禁止将sizeof应用于函数类型的表达式。

关于C ++的ISO / IEC 14882说(第5.3.3节):

“大小运算符不应用于具有函数或不完整类型的表达式,……”

标准C(ISO / IEC 9899:1999)第6.5.3.4节同样适用:

sizeof运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。”

根据ISO C11第6.5.3.4 The sizeof and _Alignof operators6.5.3.4 The sizeof and _Alignof operators ,第1小节(约束):

sizeof运算符应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。

6.3.2.1 Lvalues, arrays, and function designators6.3.2.1 Lvalues, arrays, and function designators中还有第4小节6.3.2.1 Lvalues, arrays, and function designators其中规定:

函数指示符是具有函数类型的表达式。 除了它是sizeof运算符, _Alignof运算符(65)或一元&运算符的操作数之外,具有“函数返回类型”类型的函数指示符将转换为具有“指向函数返回类型的指针”的类型的表达式。

从那里引用的脚注65澄清了这一点:

由于不会发生此转换,因此sizeof_Alignof运算符的操作数仍然是函数指示符,并且违反了6.5.3.4中的约束。

根据第4 Conformance节的4 Conformance

在本国际标准中,“应”应被解释为对实施或计划的要求; 相反,“不得”应被解释为禁止。

因此,严格符合的程序永远不应该占用函数的大小。 但是,再说一遍,它可能也应该使用正确forms的main() 🙂

但是,这里有一个漏洞。 符合条件的实施允许提供扩展“只要它们不改变任何严格符合程序的行为”(第4 Conformance4 Conformance ,第6小节)。

你可以争辩说这一种行为改变(允许sizeof(function)而不是禁止它)但是,由于原始程序首先不会严格遵守,因此该小节并不禁止它。