鉴于:
int func(int x, int y) { /* ... */ }
表达式func是函数类型。具体来说,它是 type int(int, int),这是 C 中“函数int返回两个参数的类型”的语法int。(你不会经常看到这种特定的语法,因为直接引用函数类型并不常见。)
在大多数情况下,函数类型的表达式被隐式转换为指向函数的指针;在这种情况下,指针的类型是int(*)(int, int)。
不发生这种隐式转换的上下文是:
当表达式是 unary 的操作数时&;在这种情况下,&func产生函数的地址(就像func它本身通常所做的那样);和
当表达式是 的操作数时sizeof。没有这个例外,sizeof func将产生一个函数指针的大小。相反,它是违反约束的,需要编译器进行诊断。
(附注:在函数调用中使用函数名称时确实会发生这种转换。()“运算符”(标准不这么称呼它)需要指向函数类型的前缀。)
gcc 恰好有一个非标准的扩展;它允许对函数指针和 type 进行指针运算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);