我有一个C库,使用的是这样的东西:
struct Foo {
const char *bar;
bool important;
struct Baz *baz;
}
最近,我在假设important
为false
的项目中使用了它,但是它的评估结果为true
。从结构的内存布局(转储)开始,我观察到(从一开始):
由于我的架构是x86_64
,因此我认为:
bar
成员important
成员,根据设置它的代码,它的宽度应为1B(因此为1个零字节),但同时它的宽度应为4B({ {1}}),通过检查其真实性的代码(因此其评估为sizeof int
)如果相关的话,我的平台是带有GCC发行版(4.8.5 RedHat)的CentOS 7。
我的问题是-这真的会发生吗?毫无疑问的程序员会由于sizeof(bool)的变化而遇到ABI损坏吗?有关以下内容的其他提示:
不客气。
答案 0 :(得分:4)
改变sizeof(bool)真的可以破坏旧代码吗?
是的。很容易找到错误地假设 的代码,这些代码与bool
的大小和(缺少)填充有关。
...有一个
important
成员,根据设置它的代码,该成员的宽度应为1B(因此为1个零字节),但同时它的宽度也应为4B (sizeof int
)
即使代码是C99之前的版本,代码定义类型bool
的大小也应该是sizeof(bool)
或更好,struct Foo f; sizeof(f.important)
而不是sizeof int
。 / p>
此外,尽管代码未显示如何应用这些大小,但另一个问题是填充。布局本来可以
8 byte pointer, 1 byte bool, 7 padding
8 byte pointer, 4 byte bool, 0 padding
8 byte pointer, 4 byte bool, 4 padding
4 byte pointer, 1 byte bool, 3 padding
2 byte pointer, 4 byte bool, 0 padding
etc.
更好的代码本来会使用offsetof()
来查找偏移量,而使用sizeof(object.member)
来查找大小。