我总是理解在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
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).
不发生此隐式转换的上下文是:
当表达式是一元的操作数时&; 在这种情况下,&func产生函数的地址(就像func它本身通常一样); 和
当表达式是操作数时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)
小智 5
C中的函数名是什么类型的?
它是一种功能类型.
我总是理解在C中,
func并且&func是等价的
嗯,他们不是"等同的".但是,函数会衰减为指向函数的指针.
我认为它们都应该是类型指针
这是一个不正确的假设.
并期望得到8,8的输出惊讶得到8,1.为什么是这样?
因为1.如果它编译它是UB,2.它甚至不应该首先编译,因此,你的程序可以自由地做任何事情.
| 归档时间: |
|
| 查看次数: |
1866 次 |
| 最近记录: |