【问题标题】:Why can't a function with return value be assigned to a pointer function with void?为什么不能将具有返回值的函数分配给具有 void 的指针函数?
【发布时间】:2018-01-12 09:36:27
【问题描述】:

在 C/C++ 中,以下代码运行良好。

void *pa;
void fa(void*);

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

我很困惑为什么函数的返回类型不是这样:

   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

既然fb的返回类型可以很好地丢弃(即直接调用fb()而不使用它的返回值),为什么标记的行不起作用?

为此编译器仍然抱怨。

   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]

我完全不知道为什么......

【问题讨论】:

  • 这是错误的,因为它们是不同的类型。此外,C++ 略微缩小了一般 void * 习语的范围。回到 C 的时代,为了方便起见,您必须在许多情况下使用 void *。 C++ 不鼓励使用void *,并强调正确的类型安全设计。无论你想在这里做什么,都是错误的。你需要弄清楚如何以 100% 类型安全的方式正确地实现你正在做的事情,而不是搞乱void *
  • 根本不清楚第一段代码与另一段代码有什么关系。请注意,“void”在任何地方并不意味着相同的东西 - 在void* 它意味着“任何东西”,但它本身意味着“无”。
  • @molbdnilo 此代码int* f(void); void* (*pf)() = f; 使编译器抱怨[Error] invalid conversion from 'int* (*)(int)' to 'void* (*)(int)' [-fpermissive]

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


【解决方案1】:

即使您的源代码忽略了返回值,它仍然会在函数被调用时返回,并且编译器必须生成代码来处理它。
换句话说:它只在源代码中被忽略,而不是被执行程序忽略。

如果你有

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

相当于

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

如果允许pa = fb,编译器将无法知道如果您调用pa(),它需要删除一个返回值。


关于你的第三种情况:

“返回int*的函数”与“返回void*的函数完全无关。
如果你尝试,你会看到同样的错误

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

即使您可以将 char 转换为 int。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 2023-03-20
      相关资源
      最近更新 更多