这里的问题不是严格的别名,而是结构表示要求。
首先,在 , 或 与任何其他类型之间使用别名是安全的char
(signed char
在unsigned char
您的情况下,unsigned int
. 这允许您编写自己的内存复制循环,只要它们是使用char
类型定义的。这是由C99 中的以下语言(§6.5):
6. 访问其存储值的对象的有效类型是对象的声明类型,如果有的话。[脚注:分配的对象没有声明类型] [...] 如果使用 memcpy 或 memmove 将值复制到没有声明类型的对象中,或者复制为字符类型的数组,则修改对象的有效类型对于该访问和不修改该值的后续访问,是从中复制该值的对象的有效类型(如果有的话)。对于没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型。
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 - 没有填充插入到结构中。在多个平台上使用相同的结构定义时,这可能会导致不一致。您可以手动计算数据结构成员的字节偏移量并直接引用它们,或者使用编译器特定的对齐指令来控制填充。
因此,在从网络缓冲区直接转换为本机类型或结构时必须小心。但在这种情况下,别名本身不是问题。