请问编译器对 C 结构体成员自然对齐是一个惯例,还是说有相关标准规定呢?

2021-01-22 13:11:48 +08:00
 wheeler

今天代码 review 的时候一位同事说“你的结构体代码没有 4 字节补齐”。

我以为编译器都会进行补齐,在对结构体成员布局不敏感的情况下,不需要手动补齐。如果真的内存布局敏感的场景,比如网络,进程间消息,应该用#pragma pack 之内的吧。

V 友怎么看呢?

1520 次点击
所在节点    问与答
10 条回复
XiaoxiaoPu
2021-01-22 13:32:01 +08:00
编译器会自动对齐,会浪费一点内存。
ly841000
2021-01-22 13:38:06 +08:00
平常用的 c 编译器都会自动对齐啊? 你用的是什么?
wheeler
2021-01-22 13:40:17 +08:00
@ly841000 是啊。gcc 。
linux40
2021-01-22 14:00:05 +08:00
会对齐,但不是 4 字节对齐,而是根据一套规则对齐。不打算上代码的话,自己去查 cppreference 。
QBugHunter
2021-01-22 14:46:35 +08:00
@wheeler
GCC 我记得有个选择,默认不开启,开启了回自动对齐
favourstreet
2021-01-22 15:11:10 +08:00
是 Implementation-defined 。C17 标准 6.7.2.1“结构和联合体说明符”第 14 段:Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type.
意思就是编译器自己决定。
qian19876025
2021-01-22 16:47:07 +08:00
额 网络通信需要考虑
jones2000
2021-01-22 20:06:11 +08:00
如果对外的结构体,我都强制 1 字节对齐。 内部用无所谓了。
dorentus
2021-01-22 23:33:44 +08:00
会自动补。

平时不需要字节序列化的顶多是根据目标编译器和平台的规则,可以自己调整调整字段顺序来减少补的大小😏
rainman777
2021-01-22 23:41:16 +08:00
我之前遇到过这个问题,因为没对齐导致段错误。后来用的#pragma pack (n)
当时用的 ESP8266 linux 环境下编译的一个开源红外库代码。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/747358

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX