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 -pedantic
向sizeof
发出有关错误操作数的警告(记住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 operators
节6.5.3.4 The sizeof and _Alignof operators
,第1小节(约束):
sizeof
运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。
第6.3.2.1 Lvalues, arrays, and function designators
节6.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 Conformance
节4 Conformance
,第6
小节)。
你可以争辩说这是一种行为改变(允许sizeof(function)
而不是禁止它)但是,由于原始程序首先不会严格遵守,因此该小节并不禁止它。