Tôi bị nhầm lẫn bởi các quy tắc bí danh nghiêm ngặt khi nói đến việc đúc mảng char sang các loại khác. Tôi biết rằng nó được phép để đúc bất kỳ đối tượng đến một mảng char, nhưng tôi không chắc chắn những gì sẽ xảy ra theo cách khác xung quanh.Quy tắc bí danh nghiêm ngặt khi truyền * từ * mảng char là gì?
Hãy xem này:
#include <type_traits>
using namespace std;
struct{
alignas (int) char buf[sizeof(int)]; //correct?
} buf1;
alignas(int) char buf2[sizeof(int)]; //incorrect?
struct{
float f; //obviously incorrect
} buf3;
typename std::aligned_storage<sizeof(int), alignof(int)>::type buf4; //obviously correct
int main()
{
reinterpret_cast<int&>(buf1) = 1;
*reinterpret_cast<int*>(buf2) = 1;
reinterpret_cast<int&>(buf3) = 1;
reinterpret_cast<int&>(buf4) = 1;
}
Biên soạn bằng g ++ - 5.3.0 kết quả trong cảnh báo chỉ trên dòng thứ hai và thứ ba của chính:
$ g++ -fsyntax-only -O3 -std=c++14 -Wall main.cpp
main.cpp: In function ‘int main()’:
main.cpp:25:30: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
*reinterpret_cast<int*>(buf2) = 1;
^
main.cpp:26:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
reinterpret_cast<int&>(buf3) = 1;
^
là gcc đúng trong dòng 1 và 4 là chính xác, trong khi dòng 2 và 3 thì không? Tôi khá chắc chắn dòng 4 là chính xác (đó là những gì aligned_storage
là cho), nhưng các quy tắc chơi ở đây là gì?
Cách khác không được phép. –
Tất cả những điều này là UB (không chắc chắn ý bạn là gì "rõ ràng là chính xác") –