这是其他question的后续

我试图在编译时确定特定实现是否在结构内添加了未命名的填充。诸如gcc之类的特定实现允许使用编译指示来控制结构中的填充和对齐方式,但代价是与其他实现的兼容性。由于C11的n1570草案同时需要static_assertoffset_of,因此我想使用它们来查看实现是否在成员之间使用填充。

这是代码的相关部分(所引用问题中的完整代码):

#include <stdio.h>
#include <stddef.h>
#include <assert.h>

struct quad {
    int x;
    int y;
    int z;
    int t;
};

int main() {
    // ensure members are consecutive (note 1)
    static_assert(offsetof(struct quad, t) == 3 * sizeof(int),
        "unexpected padding in quad struct");
    struct quad q;
    ...

如6.7.2.1结构和联合说明符第15节所述:



我假设如果元素在结构中的偏移量是在其之前声明的元素的大小的总和,那么这些元素之间将不存在填充,因此应连续分配它们,如果它们是相同类型,则构成一个数组。

问题是:上述假设是错误的,这是(对参考问题的评论有什么想法)为什么?

最佳答案

理论上,在t之后,结构的末尾可能会有填充,您的断言不会捕获该填充(可能是或可能不是故意的)。您的假设在其他方面是正确的,因此可以很好地使用offsetofstatic_assert来检测成员变量之间的填充。

更好的替代方法可能是:

static_assert( offsetof(struct quad, t) == sizeof(struct quad)-sizeof(int),

这也捕获结构末尾的填充。另外,如果在代码维护期间更改了结构成员,则它使断言更加灵活。

关于c - 我们可以使用static_assert来检测结构中的填充吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48148477/

10-12 15:07
查看更多