comp.lang.c faq:可以返回指向同一类型函数的指针的函数

时间:2016-09-13 14:33:32

标签: c pointers function-pointers

以下是comp.lang.c faq。

中的Question 1.22

为什么ptrfuncptr的定义必要?

typedef int (*funcptr)();     /* generic function pointer */
typedef funcptr (*ptrfuncptr)();  /* ptr to fcn returning g.f.p. */

funcptr start(), stop();
funcptr state1(), state2(), state3();

void statemachine()
{
    ptrfuncptr state = start;

    while(state != stop)
        state = (ptrfuncptr)(*state)();
}

funcptr start()
{
    return (funcptr)state1;
}

2 个答案:

答案 0 :(得分:1)

ptrfuncptr旨在作为指向各种"状态"的指针的特定指针类型。功能,与原始代码中使用的功能完全相同。试图用funcptr替换它是没有意义的。 funcptr的目的是作为"泛型"指针。它总是必须被投射到适当的"特定的"使用前的函数指针类型,在本例中为ptrfuncptr

在您的代码版本中

funcptr state = start;

state声明为返回int的函数的指针,而实际上start返回一个函数指针。形式上,这种初始化是一种约束违规(又称"甚至不会编译")因为类型不兼容。

稍后你做

state = (*state)();

尝试将int返回的(*state)()值分配给指针变量state,这没有任何意义,并且正式地也是违反约束。

依此类推。

如果您的代码编译,其行为仍未定义。但是,正式地说,由于多个约束违规,这甚至不应该编译。我确定您的编译器为您的代码版本发出了很多诊断消息。

它能够"工作的唯一原因"只是这个未定义的行为在实践中如何发挥的幸运巧合。它在这些转换期间保留了指针信息(例如具有32位int和32位指针的32位平台)。在64位平台上,工作"工作的机会要小得多。

答案 1 :(得分:1)

理解代码的关键是来自C faq的4.13

  

但是,保证所有函数指针都可以互相转换,只要它们在调用之前转换回适当的类型

我们有一个函数返回指向同一类型函数的指针。但由于我们无法直接在C中定义,我们采用了一种技巧。我们只是让函数返回一个泛型函数指针,然后将其强制转换为适当的类型。由于上述4.13,我们被允许这样做。

为什么funcptr是通用指针?它不是指向返回int的函数的指针吗?为什么这是通用的?

根据4.13,所有函数指针都可以互相转换,因此我们定义它的方式并不重要。只需确保在调用之前将其转换为正确的类型。

为什么必须定义ptrfuncptr?

因为这是state函数的类型,它们是返回函数指针的函数。

函数return (funcptr)state1;中的代码start()不应该是return (ptrfuncptr)state1;吗?因为state1是指向返回funcptr的函数的指针?

start()实际返回的是ptrfuncptr,但我们将其定义为返回funcptr的函数,因此我们只将结果转换为funcptr。我们将其转换为statemachinestate = (ptrfuncptr)(*state)();

中的正确类型

为什么不首先使用正确的类型定义所有state函数而不是执行所有指针转换?

因为这将是一个递归定义。

相关问题