Saya tahu kode ini akan menyebabkan undefined behaviour karena melanggar aturan aliasing yang ketat, karena kami menunjuk ke lokasi memori yang sama dengan tipe int dan float dan mendereferensikannya, kode dapat rusak setelah pengoptimalan kompiler dilakukan:

int main(){
 int a = 5;
 float f = *reinterpret_cast<float*>(&a);

 return (int) f;
}

Tapi bagaimana dengan cuplikan ini?

#include <iostream>

int main(){
 intptr_t p = 1234; // let's assume this is a valid address in memory.
 float f = *reinterpret_cast<float*>(p);

 return (int) f;
}

Di atas, jika kita menganggap p adalah alamat memori yang valid (tidak akan menyebabkan segfault) apakah masih memiliki UB dan melanggar aturan aliasing yang ketat? tidak ada kode lain yang menunjuk ke potongan memori itu.

Sunting

Contoh kedua saya dapat ditulis seperti ini menggunakan bit_cast:

intptr_t p = 1234; // let's assume this is a valid address in memory.
float f = *std::bit_cast<float*>(p);
c++
1
Dan 10 Mei 2021, 23:41

1 menjawab

Jawaban Terbaik

Ya, itu masih akan melanggar aturan aliasing yang ketat, karena Anda akan mencoba untuk mereferensikan pointer ke float, tetapi objek float tidak pernah tinggal di alamat ini.

Untungnya, di C++ 20 Anda dapat menggunakan std::bit_cast untuk tujuan ini. Pra-C++20 Anda bisa melakukan cast :), karena meskipun ini adalah UB, tidak ada kompiler waras yang akan menghasilkan hasil yang akan berbeda dari yang Anda harapkan, karena teknik ini ada di mana-mana.

3
SergeyA 10 Mei 2021, 20:46