为什么这个 reinterpret_cast 不能编译?

2021-12-31 00:00:00 casting c++ reinterpret-cast

我知道 reinterpret_cast 很危险,我只是为了测试它.我有以下代码:

I understand that reinterpret_cast is dangerous, I'm just doing this to test it. I have the following code:

int x = 0;
double y = reinterpret_cast<double>(x);

当我尝试编译程序时,它给了我一个错误提示

When I try to compile the program, it gives me an error saying

从float"类型到double"类型的无效转换

invalid cast from type 'float' to type 'double

这是怎么回事?我认为 reinterpret_cast 是你可以用来将苹果转换为潜艇的流氓演员,为什么这个简单的演员不能编译?

What's going on? I thought reinterpret_cast was the rogue cast that you could use to convert apples to submarines, why won't this simple cast compile?

推荐答案

也许对 reinterpret_cast 更好的思考方式是胭脂运算符,它可以转换"指向苹果就像指向潜艇一样.

Perhaps a better way of thinking of reinterpret_cast is the rouge operator that can "convert" pointers to apples as pointers to submarines.

通过将 y 分配给转换返回的值,您实际上并不是在转换值 x,而是在转换它.也就是说,y 不指向 x 并假装它指向一个浮点数.转换构造了一个 float 类型的新值,并将 x 中的值赋给它.在 C++ 中有几种方法可以进行这种转换,其中包括:

By assigning y to the value returned by the cast you're not really casting the value x, you're converting it. That is, y doesn't point to x and pretend that it points to a float. Conversion constructs a new value of type float and assigns it the value from x. There are several ways to do this conversion in C++, among them:

int main()
{
    int x = 42;
    float f = static_cast<float>(x);
    float f2 = (float)x;
    float f3 = float(x);
    float f4 = x;
    return 0;
}

唯一真正的区别是最后一个(隐式转换)将生成更高警告级别的编译器诊断.但它们在功能上都做同样的事情――在很多情况下实际上做同样的事情,就像在相同的机器代码中一样.

The only real difference being the last one (an implicit conversion) will generate a compiler diagnostic on higher warning levels. But they all do functionally the same thing -- and in many case actually the same thing, as in the same machine code.

现在如果你真的想假装 x 是一个浮点数,那么你真的想通过这样做来转换 x:

Now if you really do want to pretend that x is a float, then you really do want to cast x, by doing this:

#include <iostream>
using namespace std;

int main()
{
    int x = 42;
    float* pf = reinterpret_cast<float*>(&x);
    (*pf)++;
    cout << *pf;
    return 0;
}

你可以看到这是多么危险.事实上,当我在我的机器上运行它时的输出是 1,这绝对不是 42+1.

You can see how dangerous this is. In fact, the output when I run this on my machine is 1, which is decidedly not 42+1.

相关文章