简体   繁体   English

reinterpret_cast到函数指针

[英]reinterpret_cast to function pointer

There is the code that I've written for experiments with reinterpret_cast<T> 我用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?
}

First of all why such reinterpret_cast convertion permitted? 首先,为什么允许这样的reinterpret_cast转换? I thought such conversion is ill-formed. 我认为这种转变是不正确的。

The standard (C++11 §5.2.10/6) says 标准 (C ++11§5.2.10/ 6)说

A pointer to a function can be explicitly converted to a pointer to a function of a different type. 指向函数的指针可以显式转换为指向不同类型函数的指针。 The effect of calling a function through a pointer to a function type that is not the same as the type used in the definition of the function is undefined. 通过指向函数类型的指针调用函数的效果是未定义的,该函数类型与函数定义中使用的类型不同。 Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. 除了将“指向T1的指针”的prvalue转换为“指向T2的指针”类型(其中T1和T2是函数类型)并返回其原始类型产生原始指针值之外,这种指针转换的结果未指定。

So it is undefined behavior. 所以它是未定义的行为。

Formally calling via the pointer casted to different function type is Undefined Behavior (by C++11 §5.2.10/6). 通过指向不同函数类型的指针进行正式调用的是Undefined Behavior(C ++11§5.2.10/ 6)。

In practice you're casting away a function result of type int , that would be returned in a register. 在实践中,您将丢弃int类型的函数结果,该结果将在寄存器中返回。 So about the worst that can happen when you call via the casted pointer, is that contrary to the compiler's expectations a register has changed value. 因此,当您通过铸造指针调用时可能发生的最坏情况是,这与编译器的期望相反,寄存器已经改变了值。

Another practical consideration: C++ does not support casting between function and data pointers, but Posix effectively requires cast to void* and back to work OK. 另一个实际考虑因素:C ++不支持在函数和数据指针之间进行转换,但是Posix实际上需要转换为void*并返回工作正常。 The C++ restriction is presumably in support of Harvard architecture machines, where instructions are not retrieved via the same bus and memory as ordinary data. C ++限制可能支持哈佛架构机器,其中指令不是通过与普通数据相同的总线和存储器检索的。 But the Posix round-trip would presumably work also on such architecture, unless the data address space was much smaller than the instruction address space. 但Posix往返可能也适用于这种架构,除非数据地址空间远小于指令地址空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM