我对C/ c++严格混叠理解正确吗?
Do I understand C/C++ strict-aliasing correctly?
我读过一篇关于C/c++严格混叠的文章。我认为这同样适用于c++。
据我所知,严格混叠用于重新排列代码以实现性能优化。这就是为什么两个不同类型(在c++中是不相关的)的指针不能指向相同的内存位置。
这是否意味着只有当内存被修改时才会出现问题?除了内存对齐可能存在的问题。
例如,处理网络协议,或反序列化。我有一个字节数组,动态分配和数据包结构正确对齐。我可以将它reinterpret_cast
到我的数据包结构中吗?
char const* buf = ...; // dynamically allocated
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // [shift] satisfies alignment requirements
这里的问题与其说是严格的混叠,不如说是结构表示要求。
首先,可以安全地将char
、signed char
或unsigned char
与任何一个其他类型(在您的示例中为unsigned int
)别名。这允许您编写自己的内存复制循环,只要它们是使用char
类型定义的。这在C99(§6.5)中得到以下语言的授权:
, 6。访问其存储值的对象的有效类型是该对象的声明类型(如果有的话)。[脚注:分配的对象没有声明的类型][…]如果一个值被复制到一个没有声明类型的对象中,使用Memcpy或memmove,或者作为字符类型的数组复制,则为有效类型的已修改对象的Value是复制值的对象的有效类型(如果有的话)。为对没有声明类型的对象的所有其他访问,该对象的有效类型为只是用于访问的左值的类型。
7。对象的存储值只能由具有以下类型之一的左值表达式访问:[脚注:此列表的目的是指定对象可以或不可以别名的情况。]
- 与对象的有效类型兼容的类型,
- […]
- 字符类型。
类似的语言可以在c++ 0x草案N3242§3.11/10中找到,尽管它不清楚何时分配对象的"动态类型"(我很感激任何关于char数组动态类型的进一步参考,POD对象已被复制为具有正确对齐的char数组)。
因此,混叠在这里不是问题。然而,严格阅读该标准表明,c++实现在选择unsigned int
的表示时有很大的自由。作为一个随机的例子, unsigned int
s可能是一个24位的整数,用4个字节表示,8个填充位点缀;如果这些填充位中的任何一个与某个(常量)模式不匹配,则将其视为陷阱表示,并且对指针进行解引用将导致崩溃。这可能实现吗?也许不是。但是,从历史上看,有奇偶校验位和其他奇数的系统,因此直接从网络读取到unsigned int
, 通过严格的标准读取,是不合适的。
现在,填充位的问题在今天的大多数系统中主要是一个理论问题,但值得注意。如果你打算坚持PC硬件,你真的不需要担心它(但不要忘记你的ntohl
s -端序仍然是一个问题!)
结构使情况更糟——对齐表示取决于您的平台。我曾在一个嵌入式平台上工作,其中所有类型都有1的对齐-没有填充曾经插入到结构中。当在多个平台上使用相同的结构定义时,这可能导致不一致。您可以手动计算数据结构成员的字节偏移量并直接引用它们,或者使用特定于编译器的对齐指令来控制填充。
因此,在从网络缓冲区直接转换为本机类型或结构时必须小心。但是在这种情况下,混叠本身不是问题。
实际上,在您解引用reinterpret_cast
ed整数指针时,这段代码已经具有UB,甚至不需要调用严格混叠规则。不仅如此,如果你不够小心,直接重新解释到你的包结构可能会导致各种各样的问题,这取决于结构包装和端序。
考虑到所有这些,并且您已经调用了UB,我怀疑它"可能工作"在多个编译器上,并且您可以自由地承担这个(可能可测量的)风险。
- 我对数据结构、双向链表有一些问题
- 程序没有问 3 个问题,而是将我对第一个问题的回答用于其他两个问题
- 我对 std::unique(算法)C++有问题
- 我对C++很陌生,我被困在试图做一个循环
- 结构新手,我对如何从 void 函数中返回值并将其放入另一个函数感到困惑
- 我对 MyGraph 属性顶点名称和边权重有问题
- 为什么我的矢量不随我对其元素所做的更改而更新
- 我对模板和链接器有一些疑问
- 我对如何在 C++ 上创建一个类感到困惑
- 我对 gdb 内存地址有疑问
- 我对C++程序有一个未定义的参考,不知道如何处理它
- 我用C++做了一个计算器,但我对"type of calculator"的要求循环了两次。有人可以帮助指出我的错误吗?
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- 我对 leetcode 72 上的递归方法感到茫然
- 我对这个程序有问题.有人看到我做错了什么吗?对此相当陌生
- 我对C 中共享指针列表进行排序的功能未完成类型
- 在C 中,当我对其进行专业化时会实例化模板
- 我对 java 和 c++ 之间的"reference"感到困惑
- 我对变量在递归函数中如何工作的理解是否正确?
- 这是我对 g++ 编译器C++标准