Why can't a function with return value be assigned to a pointer function with void?

时间:2017-08-04 12:31:16

标签: c++ casting function-pointers void-pointers

In C/C++, the following code works perfectly fine.

void *pa;
void fa(void*);

int a; // or any type
pa = &a;
fa(&a);

I'm confused why this isn't true for function's return type:

   void fa(void);
   int fb(void);
   void (*pa)(void);
   int (*pb)(void);

   pa = fa; pb = fb; // OK
-> pa = fb; // Wrong, why???
   pb = fa; // Wrong, but reasonable

Since the return type of fb can be well discarded (i.e. call fb() directly without using its return value), why doesn't the marked line work?

And for this the compiler still complains.

   void* fa(void);
   int* fb(void);
   void* (*pa)(void);
   int* (*pb)(void);

   pa = fa; pb = fb; // OK
-> pa = fb; // Wrong, why???
   // pb = fa;

[Error] invalid conversion from 'int* (*)(void)' to 'void* (*)(void)' [-fpermissive]

I have totally no idea why...

2 个答案:

答案 0 :(得分:2)

Even if your source code ignores a returned value, it's still returned from the function when it's called and the compiler has to generate code to deal with it.
To put it another way: it's only ignored in the source code, not by the executing program.

If you have

int fa() {return 0;}
//...
something();
fa();
somethingelse();

it's equivalent to

int fa() {return 0;}
//...
something();
{  // Scope that delimits the returned value's lifetime.
    int imgonnaignorethismmkay = fa();
} // End special scope, destroy the return value.
somethingelse();

If pa = fb were allowed, there would be no way for the compiler to know that there's a returned value that it needs to get rid of if you call pa().


On your third case:

"function that returns int*" is completely unrelated to "function that returns void*.
You'll see the same error if you try

char f(); 
int(*p)() = f;

even though you can convert a char to an int.

答案 1 :(得分:0)

返回int的函数不是返回void的函数。您可以调用函数并忽略其返回值,但是当您创建指向函数的指针时,该类型必须完全匹配。要使用在需要返回void的上下文中返回int的函数,请使用std::function;它处理参数和返回类型中的阻抗不匹配。