C结构体打包是否有保证?

8

在C语言中,结构体的打包是否有任何保证?例如,假设sizeof(double) == 8,那么sizeof(struct { double x, y; }) == 16是否有保障?请注意,本问题与严格的别名规则相冲突,因此请假设别名是禁用的,例如,在使用-fno-strict-aliasing的gcc的情况下。

为避免进一步的猜测:本问题意在了解结构体与其明确打包的对应物的兼容性。请注意,即使在以下情况下,别名也是相关的:C结构体具有相同成员类型时是否保证在内存中具有相同布局? 。请不必担心我想要访问单个字节。


你的问题中没有包含任何别名。我担心你提到它是想要添加它,但不确定你的意图。 - StoryTeller - Unslander Monica
1
这是一个 XY 问题 吗? - Weather Vane
@mch 我不确定你的第二点是否成立。请考虑到指向不同数据类型的指针可能具有不同的大小和对齐限制,但是所有指向结构体和联合体类型的指针都具有相同的大小和对齐要求。因此,例如 char * 可能比 struct {char} * 更大,在这种情况下,该结构可能需要比 _Alignof(char) 更大的对齐方式。 - EOF
意图是使结构体与其显式打包的对应物兼容。 - Pedro
@WeatherVane:我不这么认为。 - Pedro
显示剩余2条评论
1个回答

6
C标准唯一关于结构体对齐的规定是在struct的开头不得存在填充。它不保证字段之间或结尾处的填充。C标准的第6.7.2.1节针对结构体提到了以下内容: 在结构体对象内,非位域成员和位域所在的单元地址按照它们声明的顺序递增。指向结构体对象的指针经过适当转换后,指向其初始成员(如果该成员是位域,则指向其所在的单元),反之亦然。结构体对象中可能有未命名的填充,但不能在其开头处存在。结构体或联合体的末尾可能有未命名的填充。

话虽如此,大多实现通常在结构体打包方面比较一致。大小为n字节的非结构体变量(或这种变量的数组)将倾向于以n字节边界开始。嵌套在结构体中的结构体将倾向于根据其子字段的对齐方式进行对齐。

失传的C结构体打包艺术详细介绍了这一点。


1
此外,有一种有趣的序列化方法叫做 Cap'n Proto,旨在使结构打包在不同的机器、操作系统等上得到控制和保持一致。通过模式规范化消息(结构)内容,并由 Cap'n Proto 的工具和库实现,序列化被简化为处理字节序,而这一点已经为您完成了:因此它非常非常快速。有很多值得推荐的地方。 - bazza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接