不使用由place new返回的指针时的C ++严格别名 [英] C++ strict aliasing when not using pointer returned by placement new

查看:78
本文介绍了不使用由place new返回的指针时的C ++严格别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能会导致不确定的行为吗?

Can this potentially cause undefined behaviour?

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,它仍然是未定义行为吗?还有什么变化?


char has special rules for strict-aliasing. If I use char instead of uint8_t is it still Undefined Behavior? What else changes?

正如DeadMG成员指出的那样,reinterpret_cast是依赖于实现的.如果我改用C样式的强制转换(int32_t*)storage,会发生什么变化?

As member DeadMG pointed out, reinterpret_cast is implementation dependent. If I use a C-style cast (int32_t*)storage instead, what would change?

推荐答案

由new放置返回的指针与引入别名考虑时的其他任何指针一样,都是UB引起的.您有责任确保放置对象的内存不会被不应有的别名所混淆.

The pointer returned by placement new can be just as UB-causing as any other pointer when aliasing considerations are brought into it. It's your responsibility to ensure that the memory you placed the object into isn't aliased by anything it shouldn't be.

在这种情况下,您不能假定uint8_tchar的别名,因此应用了特殊的别名规则.另外,使用uint8_t而不是char数组将毫无意义,因为sizeof()是用char而不是uint8_t表示的.您必须自己计算大小.

In this case, you cannot assume that uint8_t is an alias for char and therefore has the special aliasing rules applied. In addition, it would be fairly pointless to use an array of uint8_t rather than char because sizeof() is in terms of char, not uint8_t. You'd have to compute the size yourself.

此外,reinterpret_cast的作用完全是实现定义的,因此代码肯定没有明确定义的含义.

In addition, reinterpret_cast's effect is entirely implementation-defined, so the code certainly does not have a well-defined meaning.

要实现低级的令人不快的内存hack,原始内存仅需由char*void*T*别名,其中T是最终的目标类型-在这种情况下为int ,以及从T*可以得到的其他任何内容,例如T是派生类,并且将派生类的指针转换为指向基数的指针.任何其他情况都违反了严格的别名和鼻恶魔.

To implement low-level unpleasant memory hacks, the original memory needs to be only aliased by char*, void*, and T*, where T is the final destination type- in this case int, plus whatever else you can get from a T*, such as if T is a derived class and you convert that derived class pointer to a pointer to base. Anything else violates strict aliasing and hello nasal demons.

这篇关于不使用由place new返回的指针时的C ++严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆