为什么c ++标准不保证对象数组与其第一个元素之间的指针可互换性?

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 只有工具来按字节迭代存储.