【问题标题】:Function pointer casting parameter to void函数指针转换参数为 void
【发布时间】:2019-04-13 16:27:58
【问题描述】:

我为我的问题写了一个简单的演示(test.cpp):

#include <stdio.h>
typedef void* (*SEL)(void);

int foo(int a, int b, int c) {
    return a + b + c;
}

SEL _ptr_to_foo() {
    return (SEL)foo;
}
int main() {
    SEL sel = _ptr_to_foo();

    return 0;
}

我在我的 osx 中使用 g++ test.cpp -o test 编译它,编译器没有抱怨。

但我对这里发生的事情感到困惑。在我看来,SEL 定义了参数为void 的函数指针并返回void*。但是,函数foo 应该是一个接受三个 int 参数并返回一个 int 作为结果的函数。我认为foo 的函数指针应该声明为int (*ptr)(int, int, int) = foo; 之类的东西。为什么_ptr_to_foo 中的选角有效?这里发生了什么?

【问题讨论】:

  • "works" 是相对的。 SELfoo() 不兼容。
  • @Swordfish 我尝试通过 SEL 调用我的 foo 但由于参数错误而失败。看来 SEL 把我在 foo 中的参数信息扔掉了。这是否意味着您评论中的not compatible
  • 为什么应该转换失败?尤其是 c 风格的演员?
  • 你为什么不直接使用正确的类型?
  • 它之所以有效,是因为 C++ 语言允许这样做。它允许这样做是因为您可能希望将函数指针存储在不同的类型下,并在以后根据与它一起存储的其他信息进行回滚。

标签: c++ casting function-pointers calling-convention reinterpret-cast


【解决方案1】:

您可以将函数指针存储为错误的函数指针类型。

如果您将它们调用为错误的函数指针类型,则您的程序的行为将无法被 C++ 标准定义。

您使用的 C 风格转换变成了 reinterpret_cast&lt;SEL&gt;,这可能会做非常不安全的事情。

【讨论】:

    【解决方案2】:

    c 风格的类型转换在类型检查方面相当松懈。您应该改用static_cast。这无法编译:

    return static_cast<SEL>(foo);
    

    【讨论】:

    • 好的,这个失败了。我应该把这种 c 风格的转换视为一个错误吗?
    • 不,这不是错误,这是设计使然。在 C++ 中使用 reinterpret_cast&lt;&gt; 可以让你做同样的事情......愚蠢的事情。
    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 2021-05-09
    • 2014-09-05
    • 1970-01-01
    • 2018-12-10
    • 2020-06-11
    相关资源
    最近更新 更多