Что делает * (double *) & a? - PullRequest
0 голосов
/ 19 мая 2018

Какова цель (двойной *) здесь?Я понимаю, что:

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 голосов
/ 19 мая 2018

То, что здесь происходит, вы перечитываете a, то есть int, принудительно в double.

Позвольте мне разобрать это:

&aполучает указатель типа int * на переменную a.

Затем, с помощью (double *) вы преобразуете этот указатель в тип double *.

Наконец, с помощью * вы разыменовываете приведенный указатель на double.

Итак, все вместе, вы берете указатель на a, преобразовывает его в double*, разыменовываете его и присваиваете значениепеременная d1.

Это известно как определение типа, и, как упоминали другие, это плохо, потому что два типа int и double, вероятно, занимают различное количество байтов в памяти..

Предположим, что int определяется как 4 байта в вашей системе, а double равно 8 байтов.Тогда это проблема, потому что вы говорите своей системе: «Послушайте, вы можете прочитать следующие 8 байтов по этому адресу вместо 4 байтов, которые на самом деле являются действительными данными».Кто знает, что находится в следующих 4 байтах?Поведение - undefined , и вы в основном гарантированно читаете мусор.

0 голосов
/ 19 мая 2018

Это похоже на код ниже.У него также есть UB, если он присваивает int и получает double, но он не получает доступ к чужой памяти и не нарушает строгий псевдоним по крайней мере.

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 ;
}
0 голосов
/ 19 мая 2018

Это наказание типа, но это также неопределенное поведение.int не имеет такой же размер, как double на большинстве платформ, что означает, что приведение указателя int к указателю double и последующее чтение из него будут считывать данные стека, к которым у вас не должно быть доступак.

В буквальном смысле происходит то, что d1 присваиваются биты, хранящиеся в и около a.Поскольку эти биты произвольны (и, вероятно, считывают мусор из стека), его значение может быть примерно любым.

Само собой разумеется, что вы не должны этого делать.Type-Punning - это только едва определенное поведение в идеальных условиях, и оно определенно не использует метод, который вы здесь используете.

...