C中的函数名是什么类型的?

Bar*_*uch 33 c function

我总是理解在C中,func并且&func是等价的.我假设它们都应该是类型指针,在我的Win64系统上是8个字节.但是,我刚试过这个:

#include <stdio.h>

int func(int x, int y)
{
    printf("hello\n");
}

int main()
{
    printf("%d, %d\n", sizeof(&func), sizeof(func));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

而期望获得输出8, 8却很惊讶8, 1.

为什么是这样?到底 什么类型func?它似乎是类型char或某种等价物.
这里发生了什么?

gcc -std=c99如果它有所作为,我编译了这个.

oua*_*uah 37

C中的函数名是什么类型的?

函数名称或函数指示符具有函数类型.当它在表达式中使用时,除了它是操作数sizeof&运算符之外,它从类型"函数返回类型 "转换为类型"指向函数返回类型的指针".(这在C99,6.3.2.1p4中规定).

现在

sizeof(func)

是无效的C,因为sizeof函数类型的操作数不允许.这在sizeof运算符的约束中指定:

(C99,6.5.3.4p1约束)"sizeof运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式. "

sizeof(func)

允许在GNU C中使用

在GNU C中有一个GNU扩展允许它,在GNU C中sizeof有一个函数类型的操作数产生1:

6.23无效指针和功能指针的算法

[...] sizeof也允许在void和函数类型上使用,并返回1.

http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

  • @TheodorosChatzigiannakis因为GNU人自己很困惑.只需看看他们建议遵循的C编码风格.Aaaaargh! (8认同)
  • 为什么他们选择实施这个*和*返回1有什么理由吗?在我看来,他们创造了一种不必要的混乱来源. (5认同)
  • @TheodorosChatzigiannakis看看链接,这样做是为了允许指针算术与`void*`和指向GNU C中的函数的指针. (5认同)

Kei*_*son 12

鉴于:

int func(int x, int y) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

表达式func是函数类型.具体来说,它是类型int(int, int),它是类型" int返回两个参数的函数"的C语法int.(您不会经常看到特定的语法,因为直接引用函数类型并不常见.)

大多数情况下,函数类型的表达式被隐式转换为指向函数的指针; 在这种情况下,指针是类型int(*)(int, int).

发生此隐式转换的上下文是:

  1. 当表达式是一元的操作数时&; 在这种情况下,&func产生函数的地址(就像func它本身通常一样); 和

  2. 当表达式是操作数时sizeof.如果没有此异常,sizeof func将产生函数指针的大小.相反,它是一个约束违规,需要编译器的诊断.

(旁注:当函数调用中使用函数名时,会发生此转换.()"运算符"(标准不称之为)需要指向函数类型的前缀.)

gcc碰巧有非标准的扩展名; 它允许对函数指针和类型进行指针运算void*,就像指针上的指针算术一样char*(即,它以字节为单位运算).不幸的是,恕我直言,gcc通过kludge做到这一点,将函数类型和类型的大小设置void为1.这就是你得到的原因sizeof func == 1; 如果您启用其中一种标准符合模式(例如gcc -std=c99 -pedantic),您将收到警告.

顺便说一句,不要%d用来打印结果sizeof.sizeof产生类型的结果size_t.如果您的实现支持它(C99或更高版本),请使用%zu; 如果没有,您需要使用强制转换将size_t值显式转换为可以打印的值.例如:

printf("%lu\n", (unsigned long)sizeof &func);
Run Code Online (Sandbox Code Playgroud)

  • 你在哪里想到最后一段中的'printf("%lu \n",(unsigned long)sizeof&func)` (4认同)
  • @glglgl我认为这更像是一个案例,gcc人们希望C*程序员*知道他在做什么.我认为,这有点符合C的精神. (3认同)

小智 5

C中的函数名是什么类型的?

它是一种功能类型.

我总是理解在C中,func并且&func是等价的

嗯,他们不是"等同的".但是,函数会衰减为指向函数的指针.

我认为它们都应该是类型指针

这是一个不正确的假设.

并期望得到8,8的输出惊讶得到8,1.为什么是这样?

因为1.如果它编译它是UB,2.它甚至不应该首先编译,因此,你的程序可以自由地做任何事情.

  • @Mat可能它可以用来混淆两个程序员辩论它的行为;-) (3认同)