Luc*_*ore 5 c++ strict-aliasing language-lawyer
以下是明确定义的:
char* charPtr = new char[42];
int* intPtr = (int*)charPtr;
charPtr++;
intPtr = (int*) charPtr;
Run Code Online (Sandbox Code Playgroud)
将intPtr(在这两种情况至少之一)没有正确对齐.只是把它放在那里是非法的吗?是UB在任何阶段使用它吗?你怎么能用它,怎么不能?
首先,当然:指针在第一种情况下保证对齐(通过 \xc2\xa75.3.4/10 和 \xc2\xa73.7.4.1/2),并且在两种情况下都可以正确\n对齐。(显然,如果sizeof(int) == 1,但是\n即使情况并非如此,实现也\n不一定有对齐要求。)
澄清一下:你的演员阵容都是reinterpret_cast。
除此之外,这是一个有趣的问题,因为据我所知,就标准而言,这两种类型转换没有区别。转换的结果\n未指定(根据\xc2\xa75.2.10/7);您甚至不能保证将其转换回 achar*会得到原始值。int*(例如,在小于 a 的机器上,显然不会char*。)
当然,在实践中:标准要求\n的返回值与new char[N]可能适合它的任何值\n充分对齐,因此保证您能够执行以下操作:
intPtr = new (charPtr) int;\nRun Code Online (Sandbox Code Playgroud)\n\n考虑到默认构造函数int是无操作的,这与您的强制转换具有完全相同的效果。(并假设\n sizeof(int) <= 42。)因此很难想象第一部分失败的实现。您应该能够intPtr像使用任何其他合法获得的 一样使用\n intPtr。将其转换回 achar*会以某种方式导致与原始值不同的想法char*似乎很荒谬。
在第二部分中,所有的赌注都是关闭的:你绝对不能\n取消引用指针(除非你的实现保证\n否则),并且也很可能将其转换回\n导致char*不同的结果。(例如,想象一下一个字寻址机器,将 a 转换char*为 anint*向上舍入。然后转换回来将导致比原始值char*更高sizeof(int)。或者尝试转换未对齐的指针总是会导致\n空指针。)