将成员添加到C样式结构和向后兼容性

rub*_*nvb 7 c api struct backwards-compatibility

假设我有一个结构定义在深层的低级代码中,以最疯狂和未知的方式在整个地方使用:

struct T {
    unsigned short name_len;
    char d_name[LENGTH];
}
Run Code Online (Sandbox Code Playgroud)

使用附带的函数来填充d_name以及需要放在那里的任何内容,例如

struct T* fill( somethingOrOther* X)
Run Code Online (Sandbox Code Playgroud)

我想扩展旧的struct +函数以包含一个新变量:

struct T {
    unsigned short name_len;
    char d_name[LENGTH];
    unsigned short type_len;
    char d_type;
}
Run Code Online (Sandbox Code Playgroud)

并且函数的新版本也会用有用的东西填充d_type变量.

这种类型的改变会破坏API吗?我不能只使用新的T而不是旧的T,并另外访问新的成员?

Juk*_*ela 5

像这样扩展你的结构可能是有意义的:

struct newT {
    struct T t;
    int newElement;
    ...
}
Run Code Online (Sandbox Code Playgroud)

那么你就可以安全地使用newT指针作为T指针了;C 标准保证结构体的第一个元素之前没有填充。


R..*_*R.. 4

只要使用此 API 的代码仅获取T对象作为库返回的指针,并且不声明它们本身、malloc它们本身(使用sizeof(struct T)),或执行任何其他取决于结构大小的操作,那么应该没问题。如果调用代码访问了结构体的内容,则需要确保将新成员放在结构体的末尾。

一个可能的额外考虑因素是,如果声明的大小不合适,是否有任何代码依赖于d_name结构的末尾以便为更大的名称分配空间并存储更大的名称。我之所以提出这一点,是因为成员的名称表明该结构dirent类似于dirent.