C中的函数名是什么类型的?
我一直明白在C语言中,C中的函数名是什么类型的?,c,function,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; } #包括 int func(int
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;
}
#包括
int func(int x,int y)
{
printf(“hello\n”);
}
int main()
{
printf(“%d,%d\n”,sizeof(&func),sizeof(func));
返回0;
}
期望得到输出8,8
,却意外得到8,1
为什么会这样?什么类型的函数是func
?它似乎属于char
类型或类似类型。这是怎么回事 我用gcc-std=c99编译了这篇文章,如果它有区别的话 C中的函数名是什么类型的 函数名或函数指示符具有函数类型。在表达式中使用时,除了它是
sizeof
或&
运算符的操作数外,它从类型“函数返回类型”转换为类型“指向函数返回类型的指针”。(这在C99,6.3.2.1p4中有规定)
现在
sizeof(func)
C无效,因为函数类型的操作数不允许使用sizeof
。这在sizeof
运算符的约束中指定:
(C99,6.5.3.4p1约束)“sizeof运算符不得应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或指定位字段成员的表达式。”
但是
sizeof(func)
在GNUC中是允许的
GNU C中有一个允许它的GNU扩展,在GNU C中有一个函数类型的操作数产生1
:
6.23空指针和函数指针的算法
在void和函数类型上也允许使用[…]sizeof,并返回1
C中的函数名是什么类型的
它属于功能类型。
我一直明白在C语言中,func
和&func
是等价的
嗯,它们不是“等价物”。然而,函数确实会衰减为指向函数的指针
我认为它们都应该是指针类型
这是一个错误的假设
期望得到输出8,8却意外地得到了8,1。为什么会这样
因为1。这是UB如果它编译,2。它甚至不应该首先编译,因此,您的程序可以自由执行任何操作。给定:
int func(int x, int y) { /* ... */ }
表达式func
属于函数类型。具体来说,它的类型是int(int,int)
,这是C对“函数”类型的语法,该类型有两个int
参数返回int
(您不会经常看到这种特殊的语法,因为直接引用函数类型并不常见。)
在大多数上下文中,函数类型的表达式隐式转换为指向函数的指针;在本例中,指针的类型为int(*)(int,int)
不发生此隐式转换的上下文包括:
&
的操作数时;在这种情况下,&func
产生函数的地址(就像func
本身通常产生的那样);以及sizeof
的操作数时。如果没有此异常,sizeof func
将产生函数指针的大小。相反,它是一种约束冲突,需要编译器进行诊断()
“运算符”(标准不调用该运算符)需要指向函数类型的指针前缀。)
gcc恰好有一个非标准扩展;它允许对函数指针和类型void*
进行指针运算,就像对char*
指针进行指针运算一样(即,它以字节为单位操作)。不幸的是,IMHO,gcc通过一个乱码实现了这一点,将函数类型和类型的大小void
设置为1。这就是为什么您会得到sizeof func==1
;如果您启用一个标准一致性模式(例如,gcc-std=c99-pedantic
),您将得到警告
顺便说一句,如果您的实现支持,请不要使用%d
打印sizeof
的结果sizeof
生成类型为size\t
的结果,使用%zu
;如果不是,则需要使用强制转换将大小\u t
值显式转换为可以打印的值。例如:
printf("%lu\n", (unsigned long)sizeof &func);
名称在C中没有类型。某些类型的名称表示具有类型的实体,如typedef名称、对象或函数。其他类型的名称表示没有类型的实体,如预处理器符号或
goto
标签。但其他类型的名称仅表示类型本身,即typedef
名称
函数名表示具有函数类型的实体。该函数类型包括返回类型和有关参数的信息(可能不完整)
当函数用作值时,它们总是作为指向函数类型的指针进行操作。这样的函数不能在可移植的C程序中传递,但指向函数的指针可以传递
从概念上讲,即使在像foo()
这样的直接调用中,所发生的情况是foo
,一个表示函数的表达式,在求值时被隐式转换为指向函数值的指针。()
函数调用后缀操作符然后通过该指针调用函数
有一条规则是,具有函数类型的表达式生成指针值,除非该表达式是&
(的地址)或sizeof
运算符的操作数。func
和&func
仅为