你可以对指向另一个对象的char*进行算术运算

Pas*_* By 7 c++ language-lawyer

这是读取普通可复制对象的字节的常用方法

Object obj;
auto p = reinterpret_cast<char*>(&obj);
for(size_t i = 0; i < sizeof(obj); i++)
    consume(p[i]);
Run Code Online (Sandbox Code Playgroud)

问题不在于严格别名,char*而是允许别名.问题出在[expr.add]的这段话

当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果表达式P指向具有元素x[i]的数组对象xn元素,则表达式P + JJ + P(其中J具有值j)指向(可能是假设的)元素x[i + j]if 0 ? i + j ? n; 否则,行为未定义.同样,表达式P - J指向(可能是假设的)元素x[i ? j]if 0 ? i ? j ? n; 否则,行为未定义.

假设元素所指的地方

过去的阵列的最后一个元素的指针xn元素被认为是等效的指针的假想元件x[n]用于此目的的

也就是说,如果算术在指向数组的指针上,并且结果仍在其范围内,则这是合法的.

但是,这里显然没有char[sizeof(Object)],我们可以对该指针进行算术运算吗?

请注意,读取对象字节的合法解决方案是std::memcpy对象.但如果这是唯一的解决方案,那么就要问,char*如果你几乎无法做任何事情,为什么要允许别名呢?

iva*_*ult 1

根据引号,指针算术应该是合法的。一个Object实例obj可以被视为char[sizeof(Object)]。所以,它是一个元素数组n(注意是nsizeof(Object)。标准允许在该数组的范围内加上一个超出该数组范围的假设元素进行指针算术。这是由于小于或等号

\n\n
\n

0 \xe2\x89\xa4 i + j \xe2\x89\xa4 n

\n
\n\n

表达。

\n\n

从字面上看,reinterpret_cast<char*> (&obj) + sizeof(Object)很好,因为它指向假设的元素a[j],其中j = sizeof(Object)和 它小于或等于数组的大小,即sizeof(Object)

\n\n

所以,答案是肯定的。

\n\n

否则std::end对于数组来说将是 UB。

\n

  • 它到底在哪里说“obj”可以“查看”为“char[sizeof(Object)]”? (2认同)