在C程序中,函数指针通常使用typedef
声明:
typedef int (*PFN_RETURNING_INT)(int, int);
*
表示这是一个指针,指向一个接受两个int
参数并返回int
的函数。
我在挖掘Windows SDK头文件,并在通过C预处理器运行rpcdec.h
后发现了这个:
typedef void __stdcall
RPC_INTERFACE_GROUP_IDLE_CALLBACK_FN (
RPC_INTERFACE_GROUP IfGroup,
void* IdleCallbackContext,
unsigned long IsGroupIdle
);
注意,没有*
来表示“指针性”。它似乎是为一个 * 函数 * 定义了一个typedef,而不是一个指向函数的 * 指针 *。在我的印象中,函数不是C类型系统中的一等实体,所以我对如何理解typedef感到困惑。
当我用RPC_INTERFACE_GROUP_IDLE_CALLBACK_FN
类型的参数定义一个函数时,MSVC编译器很乐意接受它,并将其视为函数的 * 指针 *。typedef
是有效的C吗?我应该把typedef
解释为定义一个函数的指针名吗?
编辑:我修改了一些以下程序:
#include <stdio.h>
typedef void (*PFN)(int x);
typedef void FN(int x);
void print(int x)
{
printf("%d\n", x);
}
void doit(FN fn)
{
fn(3);
}
void doit_p(PFN pfn)
{
pfn(3);
}
int main ()
{
doit(print);
doit_p(print);
// FN x = print; // Uncommenting these two lines fails to compile.
// doit(x);
exit(0);
}
有趣的是,编译器很乐意接受这个程序,但是如果我取消注解main
中的两行,它会抱怨“initialization of a function
“。它让我想起了C中数组参数的行为,它“衰减”为指针。但这是贝瓦维尔故意的,还是偶然的?
3条答案
按热度按时间bjp0bcyl1#
.我的印象是函数在C类型系统中不是一等实体,所以我对如何理解typedef感到困惑。
typedef
声明了一个类型的名称。它不声明函数或其他实体,也不传递函数或以其他方式在表达式中使用函数,因此函数是否是第一类实体并不重要:名称只是标识类型,而这并不要求类型是一级类型。当我定义一个带有参数类型的函数时...
将参数声明为函数会自动调整为指向函数的指针声明。C 2018 6.7.6.3 8说:
如6.3.2.1所示,将参数声明为“返回 * 类型 * 的函数”应调整为“返回 * 类型 * 的函数指针"。
此外,当函数指示符用于表达式中而不是作为一元
&
的操作数时,它会自动转换为指向函数的指针,根据C 2018 6.3.2.1 4:sizeof
运算符的操作数[失败,因为将sizeof
应用于函数违反了约束],或者一元&
运算符,否则类型为“function returning type”的函数指示符将转换为类型为“pointer to function returning type"的表达式。cu6pst1q2#
typedef(s)引入了同义词,或者换句话说,不同类型的别名。函数有类型。所以你可以使用typedef声明来引入函数类型的别名。
这里有一个简单的例子。
hiz5n14c3#
这个定义是有效的。在使用定义时,您可能必须使用
*
: