san*_*orn 5 c++ undefined-behavior reinterpret-cast c++11 c++17
根据这个
http://eel.is/c++draft/basic.compound#4
如果出现以下情况,则两个对象a和b是指针可互换的:
- 它们是同一个对象,或者
- 一个是union对象,另一个是该对象的非静态数据成员([class.union]),或
- 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的第一个基类子对象([class.mem]) ), 要么
- 存在对象c,使得a和c是指针可互换的,并且c和b是指针可互换的.
如果两个对象是指针可互换的,则它们具有相同的地址,并且可以通过reinterpret_cast从指向另一个的指针获得指向一个对象的指针.[ 注意:数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址. - 结束说明]
为什么c ++标准不保证对象数组与其第一个元素之间的指针可互换性,而保证类及其第一个成员?
为什么这是未定义的行为?
char carr[8];
char& ch0 = carr[0];
auto& carr2 = reinterpret_cat<char (&) [8]>(ch0); // Is this considered undefined behavior?
// Because ch0 (char&) and carr2 (char(&)[8]) are not "pointer-interconvertible".
// So they can not use reinterpret_cast "definedly".
// Array and its first element are not "pointer-interconvertible"
// eventhough they share the same address.
Run Code Online (Sandbox Code Playgroud)
虽然这是标准本身的一个例子.
http://www.eel.is/c++draft/basic.types#2
#define N sizeof(T)
char buf[N];
T obj; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std?::?memcpy,
// obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj
// of scalar type holds its original value
Run Code Online (Sandbox Code Playgroud)
想想T = char [N]?好吧,不会&obj成为char(&)[N]?为什么std :: memcpy如此优越以至于它可以使用char(&)[N]而我们却不能.
这太有趣了.
我很想知道为什么标准有意制造char *,std::memcpy 只有工具来按字节迭代存储.