0

当我需要查找函数类型长度时,我使用 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;
}               
4

5 回答 5

3

sizeof运算符不得用于函数类型,这是 ISO/IEC C 标准明确禁止的。所以返回值没有意义。

参考ISO/IEC 9899:201x §6.5.3.4

sizeof运算符不应应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或指定位域成员的表达式。

我想启用-pedantic标志应该发出警告。

于 2013-09-24T18:14:20.963 回答
1

您试图找到函数本身的大小而不是它的返回值。为了找到返回值的类型,你需要添加一对括号,告诉编译器你需要函数调用表达式的类型,像这样:

printf ("int foo () %lu\n", sizeof (foo()));  
printf ("double bar () %lu\n", sizeof (bar()));

请注意,这些函数不会被调用:它们的返回类型的 sizeof 将在编译时计算出来。

ideone 上的演示

于 2013-09-24T18:14:21.447 回答
0

尽管标准说sizeof运算符不得应用于具有函数类型的表达式”(第 6.5.3.4/1 节),但在 GNU C 中,这样做的结果是明确定义的:

"sizeof也允许在 void 和函数类型上,并返回 1"
~ GCC,6.23 void 指针和函数指针的算术

还可以看看:为什么 C 中函数的大小总是 1 字节?

于 2013-09-24T18:16:19.957 回答
0

sizeof 不应应用于具有函数类型的变量。因此,您所看到的基本上是未定义的行为。理想情况下,编译器应该抱怨它..

于 2013-09-24T18:14:24.070 回答
0

应用于sizeof函数名是违反约束的,需要任何符合标准的编译器进行诊断。gcc 默认情况下不符合要求,但可以(几乎)使用正确的命令行选项进行设置,例如:

gcc -std=c99 -pedantic

(替换c99c90c11如果你喜欢)。

gcc 有一个扩展,允许void*对函数指针进行指针运算。(ISO 标准允许这样的扩展,但符合标准的编译器仍必须诊断出任何违反约束的情况。)例如,将 1 加到函数指针上,将其前移 1 个字节。

不幸的是,恕我直言,gcc 开发人员选择通过将函数和void类型的大小设为 1 来做到这一点。指针算术的行为由此而来,但它有一个缺点,即尝试计算函数或 void 表达式的大小不被拒绝。

标准 C 没有提供确定函数大小的方法;它甚至没有讨论这样的概念。据我所知,gcc 没有提供这样做的扩展;sizeof func产生一个虚构的值 1,与函数的代码大小无关。

您始终可以确定函数指针的大小,通常为 4 或 8 个字节,但当然这不是函数本身的大小。你不能通过应用sizeof函数名来做到这一点。

如果 C 程序可以获得函数的大小(大概是实现它的代码的大小),那么除了显示它之外,我想不出它可以对这些信息做什么有用的事情。如果这是您要查找的信息,您可能会检查程序集列表或目标文件。例如,在类 Unix 系统上, 的输出nm foo.o显示每个函数的地址;这通常可以告诉您每个函数的代码大小(可能最后一个函数除外)。这都是非常系统特定的。

于 2013-09-24T18:32:10.500 回答