示例代码:
main ()
{
printf ("size = %d\n", sizeof (main));
}
答案 0 :(得分:13)
C标准禁止它 - 当使用gcc -pedantic
进行编译时,会产生invalid application of ‘sizeof’ to a function type
警告。
但gcc
编译它并返回1
sizeof(main)
,它不是函数指针的大小。
它似乎与编译器有关。
答案 1 :(得分:6)
The sizeof Operator
sizeof unary-expression sizeof ( type-name )
操作数可以是一元表达式的标识符,也可以是类型转换表达式(即括在括号中的类型说明符)。 一元表达式不能表示位字段对象,不完整类型或
function designator
。结果是无符号整数常数。标准头文件STDDEF.H将此类型定义为size_t
。
使用编译标志-Wall -pedantic
向sizeof
发出有关错误操作数的警告(记住sizeof
是编译时操作符),代码:
$ cat sizeof.c
#include<stdio.h>
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 The sizeof operator
1118 -
sizeof
运算符不应用于具有函数类型或不完整类型的表达式,此类型的带括号的名称或指定的表达式位场成员
1127 - 结果的值是实现定义的,其类型(无符号整数类型)是size_t
,在<stddef.h>
(和其他标题)中定义
此外,size_t
的正确格式字符串为%zu
,如果Microsoft编译器不存在,则可以使用%lu
并将返回值转换为unsigned long
}。
答案 2 :(得分:5)
ISO C ++禁止将sizeof
应用于函数类型的表达式。
ISO / IEC 14882关于C ++的说法(第5.3.3节):
“大小运算符不应用于具有函数或类型不完整的表达式,...”
与标准C(ISO / IEC 9899:1999)第6.5.3.4节相同:
“ sizeof运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。” EM>
答案 3 :(得分:1)
根据ISO C11部分6.5.3.4 The sizeof and _Alignof operators
,第1小节(约束):
sizeof
运算符 不应 应用于具有此类型的带括号的名称的具有函数类型或不完整类型的表达式,或者到指定位字段成员的表达式。
6.3.2.1 Lvalues, arrays, and function designators
部分还有第4小节,其中指出:
函数指示符是具有函数类型的表达式。除非它是
sizeof
运算符,_Alignof
运算符(65)或一元&
运算符的操作数,否则函数指示符的类型为“返回函数” type“转换为具有类型的表达式”指向函数返回的指针 输入 “”。
从那里引用的脚注65澄清了这一点:
因为没有发生这种转换,
sizeof
或_Alignof
运算符的操作数仍然是函数指示符,并且违反了6.5.3.4中的约束。
根据4 Conformance
部分:
在本国际标准中,“应”应被解释为对实施或计划的要求;相反,“不得”被解释为 禁令。
因此,严格遵守的程序永远不应该占用函数的大小。但是,再一次,它可能也应该使用正确形式的main()
: - )
然而,这里有一个漏洞。允许符合条件的实现提供扩展“,前提是它们不会严格改变任何行为
符合计划“(4 Conformance
部分,6
}。
你可以说这个是一个行为改变(允许sizeof(function)
而不是禁止它)但是,由于原始程序首先不会严格遵守,小节不禁止它。