*(double *)& a有什么作用?

时间:2018-05-18 21:36:08

标签: c++ type-punning

这里(双*)的目的是什么? 我理解:

double d1 = *&a;

会给我a的地址值,但是加上(double *)将值1.4854e-313存储到d1中。为什么是这样?什么是打字?我是否已从未定位的内存中写入或读取?

int main () {
    int a = 17;
    double d1 = *(double*)&a ;
    std :: cout << "\na = " << a << ", &a = " << & a ;
    std :: cout << "\nd1 = " << d1 << ", &d1 = " << & d1 ;
}

3 个答案:

答案 0 :(得分:2)

这是类型惩罚,但它也是未定义的行为。在大多数平台上,intdouble的大小不同,这意味着向int指针投射double指针,然后从中读取,将从堆叠您无法访问的数据。

从字面上看,正在发生的事情是d1被分配了a及其周围存储的比特。因为这些位是任意的(并且可能从堆栈中读取垃圾),所以它的值几乎可以是任何东西。

不言而喻,你不应该这样做。在理想情况下,Type-Punning只是几乎没有定义的行为,绝对不会使用你在这里使用的方法。

答案 1 :(得分:2)

这里发生的事情是,您正在a重新int,强制转移到double

让我分解一下:

&a获取int *类型的指针到变量a

然后,使用(double *),您将重新指定此类型double *

最后,使用*解除引用指向double的指针。

所以,总而言之,您将指针指向a,将其重新标记为double*,取消引用它,并将值指定给变量d1

这被称为类型惩罚,正如其他人所提到的那样,这很糟糕,因为intdouble这两种类型可能在内存中占用不同的字节数。

假设int在您的系统上定义为4个字节,double为8个字节。然后这是一个问题,因为你告诉你的系统“嘿,看,你可以在这个地址读取接下来的8个字节,而不是实际有效数据的4个字节。”谁知道接下来的4个字节是什么?行为是 undefined ,你基本上保证读垃圾。

答案 2 :(得分:0)

它与下面的代码类似。如果它分配int并获得double,它也有UB,但它不会访问外星人的内存,也不会破坏严格的别名。

union mixed_types {
    int a;
    double d1;
};

int main () {
    mixed_types bad;
    bad.a = 17;
    double d1 = bad.d;
    std :: cout << "\na = " << a << ", &a = " << & a ;
    std :: cout << "\nd1 = " << d1 << ", &d1 = " << & d1 ;
}