在一个旧程序中,我通过分配一个无符号字符数组将数据结构序列化为字节,然后通过以下方式转换整数:
*((*int)p) = value;
(其中,p
是要存储的值)。unsigned char*
value
这工作正常,除非在 Sparc 上编译时由于访问内存对齐不正确而触发异常。这很有意义,因为具有不同大小的数据元素p
很快就会变得不对齐,并在用于存储 int 值时触发错误,其中底层 Sparc 指令需要对齐。
这很快被修复(通过逐字节将值写入 char 数组)。但是我对此有点担心,因为多年来我在许多程序中都使用了这种结构而没有问题。但很明显,我违反了一些 C 规则(严格别名?),虽然这种情况很容易被发现,但由于优化编译器等,这些违规行为可能会导致其他类型的未定义行为更加微妙。我也有点困惑,因为我相信这些年来我在很多 C 代码中都看到过这样的结构。我正在考虑将硬件交换的数据结构描述为结构的硬件驱动程序(当然使用 pack(1)),并将它们写入硬件寄存器等。所以这似乎是一种常用技术。
所以我的问题是,以上到底违反了哪些规则,以及实现用例的正确 C 方法是什么(即将数据序列化为无符号字符数组)。当然,可以为所有函数编写自定义序列化函数,逐字节写出,但这听起来很麻烦,效率也不高。
最后,是否可以通过违反此别名规则来预期一般的不良影响(对齐问题等)?