在函数指针赋值中进行转换

时间:2015-07-20 19:18:12

标签: c++ c

以下函数指针赋值如何:

exit = (void (*)()) &jump;

与...不同:

exit = &jump;

其中exit是一个定义为的函数指针:

void (*exit) ();

和'jump'是一个声明为:

的函数
void jump();

3 个答案:

答案 0 :(得分:9)

exit = (void (*)()) &jump;

第一个使用强制转换。这很危险,因为它可能搞砸你的程序,而不会让你知道类型是否匹配,因为它不会在编译时被捕获。 / p>

所以,如果你这样做:

int func() {return 1;}
auto exit = (void (*)()) &func;

......那会很糟糕。但是,如果您执行以下操作会更好:

exit = &jump;

第二个使用编译时类型检查。这更安全,因为编译器将在编译时检查类型这为您提供了更强的类型保证。

最好的选择是使用static_cast<void(*)()> 这是类型安全的,并告诉程序员你想要做的更多的意图。

auto exit = static_cast<void(*)()>(&func);

如果你有C ++,你可以尝试以下方法:

如果您不想关注类型,请使用auto

auto exit = &func

这将确保类型匹配。 如果要检查类型,请使用{C} 11及更高版本中存在的typeid().name中的<typeinfo>

std::cout << typeid(exit).name << std::endl;

虽然这通常会为函数提供一些奇怪的输出,但您可能会发现一些可以帮助您的信息,如果这两种类型不同,最好的信息就是。

这是一个工作示例,在运行时使用函数指针转换显示问题: http://coliru.stacked-crooked.com/a/47f74e8b6f389812

答案 1 :(得分:3)

它们非常相似。

在C中,如果功能和类型完全按照描述:

void (*exit) ();
void jump();
exit = (void (*)()) &jump;
exit = &jump;

是完全相同的。

现在当我更改jump时会发生什么:

int jump();

现在我们正在运行未定义的行为,如果我们在之后调用exit,则不会出现错误或警告:

exit = (void (*)()) &jump;

但是我们得到了一个类型错误:

exit = &jump;

此外,可能会出现更微妙的差异 - 例如jump可能会获得调用约定,因此无法存储在exit中,并且事情会中断。

在C ++中,还有另一个细微差别。如果jump是一个重载函数, exit不是原始函数指针(但是,例如,std::function<void()>),第一个可以编译而第二个可能不编译。将名称转换为函数指针类型可以触发重载解析,没有它,某些代码就无法工作。

然而,使用static_cast<void(*)()>会更安全。

答案 2 :(得分:0)

这两项任务具有相同的效果。第一种方式&#34;演员&#34; &jump指向不带参数的函数的指针并返回void,但&jump已经是那个!