当我需要找到函数类型的长度时,我习惯使用sizeof()来完成它。
预期结果是4个字节和8个字节,但现在,结果是通过GCC的1个字节。
为什么输出是1字节,而不是4字节和8字节?
#include <stdio.h>
int foo ();
double bar ();
int
main (void)
{
printf ("int foo () %lu\n", sizeof (foo));
printf ("double bar () %lu\n", sizeof (bar));
}
double
bar (void)
{
return 1.1;
}
int
foo (void)
{
return 0;
}
答案 0 :(得分:3)
sizeof
运算符不得用于函数类型,这是ISO / IEC C标准明确禁止的。所以返回值没有意义。
参考 ISO / IEC 9899:201x§6.5.3.4:
sizeof
运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。
我想启用-pedantic
标志会引发警告。
答案 1 :(得分:1)
您正在尝试查找函数本身的大小而不是其返回值。为了找到返回值的类型,您需要添加一对括号来告诉编译器您需要函数调用表达式的类型,如下所示:
printf ("int foo () %lu\n", sizeof (foo()));
printf ("double bar () %lu\n", sizeof (bar()));
请注意,函数 not 将被调用:它们的返回类型的sizeof将在编译时计算出来。
答案 2 :(得分:0)
sizeof不应该应用于具有函数类型的变量。所以,你所看到的基本上是一个未定义的行为。理想情况下,编译器应该抱怨它..
答案 3 :(得分:0)
虽然标准说“sizeof
运算符不应用于具有函数类型”(§6.5.3.4/ 1)的表达式,但在GNU C中,结果为这样做很明确:
“
sizeof
也允许在void和on函数类型上,并返回1”
〜GCC, 6.23 Arithmetic on void- and Function-Pointers
答案 4 :(得分:0)
将sizeof
应用于函数名称是约束违规,需要来自任何符合标准的编译器的诊断。 gcc默认情况下不符合要求,但可以使用正确的命令行选项(几乎)进行,例如:
gcc -std=c99 -pedantic
(如果您愿意,可以c99
或c90
替换c11
。
gcc有一个扩展,允许在void*
和函数指针上进行指针运算。 (这些扩展是ISO标准允许的,但是符合标准的编译器仍然必须诊断任何约束违规。)例如,向函数指针添加1会使其前进1个字节。
不幸的是,恕我直言,gcc开发人员选择通过赋予函数和void
类型大小为1来做到这一点。指针算法的行为遵循这一点,但它有尝试计算大小的缺点函数或void表达式不被拒绝。
标准C没有提供确定函数大小的方法;它甚至没有讨论这样一个概念。据我所知,gcc没有提供这样做的扩展; sizeof func
产生的虚构值为1,而不是与函数的代码大小相关的任何值。
您始终可以确定函数指针的大小,通常为4或8个字节,但当然这不是函数本身的大小。而且,通过将sizeof
应用于函数名称,您无法做到这一点。
如果C程序可以获得函数的大小(可能是实现它的代码的大小),我想不出除了显示它之外它可以对该信息做什么有用。如果这是您要查找的信息,您可以检查程序集列表或目标文件。例如,在类Unix系统上,nm foo.o
的输出显示每个函数的地址;通常可以告诉你每个函数的代码大小(除了最后一个函数)。这些都是特定于系统的。