这可能会导致未定义的行为吗?
uint8_t storage[4];
// We assume storage is properly aligned here.
int32_t* intPtr = new((void*)storage) int32_t(4);
// I know this is ok:
int32_t value1 = *intPtr;
*intPtr = 5;
// But can one of the following cause UB?
int32_t value2 = reinterpret_cast<int32_t*>(storage)[0];
reinterpret_cast<int32_t*>(storage)[0] = 5;
char
对于严格别名有特殊的规则。如果我使用char
代替uint8_t
它仍然是未定义的行为吗?还有什么变化?
正如DeadMG成员指出的那样,reinterpret_cast
取决于实现。如果我使用 C 风格的强制转换(int32_t*)storage
相反,会发生什么变化?
当考虑到别名时,placement new 返回的指针可能与任何其他指针一样导致 UB。您有责任确保放置对象的内存不会被任何不应该的东西别名。
在这种情况下,您不能假设uint8_t
是一个别名char
因此应用了特殊的别名规则。此外,使用数组是毫无意义的uint8_t
而不是char
因为sizeof()
是在char
, not uint8_t
。你必须自己计算尺寸。
此外,reinterpret_cast
的效果完全是实现定义的,因此代码当然没有明确定义的含义。
为了实现低级的令人不愉快的内存黑客,原始内存只需要使用别名char*
, void*
, and T*
, where T
是最终目的地类型 - 在本例中int
,加上您可以从T*
,比如如果T
是一个派生类,并且您将该派生类指针转换为指向基类的指针。其他任何内容都违反了严格的别名和你好鼻恶魔。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)