我已经为reinterpret_cast<T>
#include <iostream>
#include <cstdlib>
using std::cout;
using std::endl;
int foo()
{
cout << "foo" << endl;
return 0;
}
void (*bar)();
int main()
{
bar = reinterpret_cast<void (*)()>(foo); //Convertion a function type to a pointer to function type
bar(); //displays foo. Is it UB?
}
首先允许这样的reinterpret_cast
转换?我认为这种转变是不正确的。
答案 0 :(得分:3)
The standard(C ++11§5.2.10/ 6)说
可以将指向函数的指针显式转换为指向不同类型函数的指针。通过指向函数类型的指针调用函数的效果是未定义的,该函数类型与函数定义中使用的类型不同。除了将“指向T1的指针”的prvalue转换为“指向T2的指针”类型(其中T1和T2是函数类型)并返回其原始类型产生原始指针值之外,这种指针转换的结果未指定
所以它是未定义的行为。
答案 1 :(得分:2)
通过指向不同函数类型的指针正式调用Undefined Behavior(C ++11§5.2.10/ 6)。
在实践中,您将丢弃类型为int
的函数结果,该结果将在寄存器中返回。因此,当您通过转换指针调用时可能发生的最坏情况是,这与编译器的期望相反,寄存器已经改变了值。
另一个实际考虑因素:C ++不支持在函数和数据指针之间进行转换,但Posix实际上需要强制转换为void*
并返回工作正常。 C ++限制可能支持哈佛架构机器,其中指令不是通过与普通数据相同的总线和存储器检索的。但Posix往返可能也适用于这种架构,除非数据地址空间远小于指令地址空间。