我是C语言新手。下面的代码片段来自我阅读的一本书。
struct S {
int i; double d; char c;
};
int main(void) {
unsigned char bad_buff[sizeof(struct S)];
_Alignas(struct S) unsigned char good_buff[sizeof(struct S)];
struct S *bad_s_ptr = (struct S *)bad_buff; // wrong pointer alignment
struct S *good_s_ptr = (struct S *)good_buff; // correct pointer alignment
}
作者指出bad_buff
可能对成员访问表达式有不正确的对齐。我很难理解这个声明。如果我们使用bad_buff
,会出现什么问题?
1条答案
按热度按时间46scxncf1#
正确答案是:如果你是一个C语言的初学者,你就在深水沃茨,因为这是一个相当高级的主题。我的经验法则是,初学者不应该出于任何目的使用强制转换操作符,因为这样做有很多陷阱。
从原始字符字节数组到结构类型有两个问题:
(As你可以安全地从一个结构体转换到一个字符字节数组,但不能反过来。
没有快速解决方案来解决这两个问题。如果你知道一个结构体有填充字节以及它们在哪里,那么你可以这样做:
这解决了严格的别名问题和初始对齐问题,但它没有解决单个结构成员可能具有填充字节的问题。为此,您需要一些非标准的方法,如
#pragma pack(1)
。这反过来又是有问题的,因为填充是有原因的,如果你打包了结构,你可能无法按预期访问某些成员。结构体总体上是不可移植的,不适合接近金属结构的东西,如数据通信协议或寄存器Map。唯一真正可移植的方法是编写一个序列化/重复化函数,该函数逐个复制单个结构体成员。