gpt4 book ai didi

c - 结构末尾的填充物用于 future 增长

转载 作者:行者123 更新时间:2023-12-04 09:54:24 27 4
gpt4 key购买 nike

document Ulrich Drepper 称为“图书馆设计、实现和维护的良好实践”(第 5 页底部):

[...] the type definition should always create at least a minimal amount of padding to allow future growth

[...]

Second, a structure should contain at the end a certain number of fill bytes.

struct the_struct
{
int foo;
// ...and more fields
uintptr_t filler[8];
};

[...]

If at a later time a field has to be added to the structure the type definition can be changed to this:

struct the_struct
{
int foo;
// ...and more fields
union
{
some_type_t new_field;
uintptr_t filler[8];
} u;
};

我看不出在结构末尾添加这个填充符有什么意义。是的,这意味着在向结构添加新字段 (new_field) 时,它实际上并没有增长。但是,将新字段添加到您不知道自己将需要它们的结构中,这不是全部意义所在吗?在这个例子中,如果你想添加的不是一个字段而是 20 个怎么办?为了以防万一,您是否应该使用 1k 字节的填充符?另外,为什么结构的大小在库的后续版本中不改变很重要?如果库提供干净的抽象,那应该没关系吧?最后,使用 64 字节的填充符(8 uintpr_t(是的,不一定是 64 字节))听起来像是在浪费内存……

该文档根本没有详细说明这一点。对于为什么“在结构末尾添加填充符以规划 future 增长”这个建议是一个好建议,您有什么解释吗?

最佳答案

根据具体情况,是的,结构的大小对于二进制兼容性可能很重要。

考虑 stat() .通常这样称呼:

struct stat stbuf;
int r = stat(filename, &stbuf);

使用此设置,如果 stat 结构的大小发生变化,则每个调用者都将无效,并且需要重新编译。如果被调用代码和调用代码都是同一个项目的一部分,那可能不是问题。但是如果(如 stat() 的情况,它是对 Unix/Linux 内核的系统调用)有很多调用者在那里,几乎不可能强制他们全部重新编译, 所以这意味着 stat 结构的大小永远不能改变。

这类问题主要出现在调用者分配(或检查/操作)结构的实际实例时。另一方面,如果结构的内部只由库代码分配和操作——如果调用代码只处理指向结构的指针,而不试图解释指向的结构——它可能结构是否发生变化无关紧要。

(现在,综上所述,如果结构必须更改大小,可以采取各种其他措施来缓解问题。在某些库中,调用者分配结构的实例,但随后将两个指向结构的指针,以及调用者知道的结构的大小,向下进入库代码。然后,较新的库代码可以检测到不匹配,并避免设置或使用较旧的调用者较新的字段没有分配空间。我相信gcc至少实现了特殊的钩子(Hook),这样glibc就可以实现相同结构的多个版本,以及使用它们的库函数的多个版本,这样就可以使用正确的库函数对应于特定调用者使用的结构版本。回到 stat(),例如,在 Linux 下至少有两个不同版本的 stat结构,一种为文件大小分配 32 位,另一种分配分配 64.)

关于c - 结构末尾的填充物用于 future 增长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57946935/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com