我们可以使用 static_assert 来检测结构中的填充吗? [英] Can we use static_assert to detect padding in a struct?

查看:30
本文介绍了我们可以使用 static_assert 来检测结构中的填充吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是另一个问题

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

I was trying to establish at compile time whether a specific implementation had added unnamed padding inside a struct. Specific implementation like gcc allow to use pragmas to control padding and alignment in structs but at the price of compatibility with other implementations. As both static_assert and offset_of are required by the n1570 draft for C11, I wanted to use them to see whether an implementation used padding between members.

这是代码的相关部分(参考问题中的完整代码):

Here is the relevant part of code (full code in referenced question):

#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 所述:

As 6.7.2.1 Structure and union specifiers § 15 says:

在结构对象中,非位域成员和位域所在的单元驻留的地址按其声明的顺序增加.一个指向 a适当转换的结构对象指向其初始成员(或者如果该成员是位域,然后到它所在的单元),反之亦然.可能有无名在结构对象内填充,但不在其开头.

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

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

I assumed that if the offset of an element in the structure was the sum of the sizes of the elements declared before it, then no padding could exist between those elements and they should be consecutively allocated thus contituting an array if they were of same type.

问题是:上面的假设是错误的吗?它是(对参考问题的评论让我们想想)为什么?

The question is: is the above assumption wrong and it it is (what comments on the reference question let think) why?

推荐答案

理论上在 t 之后结构的末尾可能会有填充,你的断言没有捕捉到(这可能或可能不是有意的).您的假设在其他方面是正确的,这是很好地使用 offsetofstatic_assert 来检测成员变量之间的任何填充.

There may in theory be padding at the end of the struct after t, which your assert does not catch (which may or may not be intended). Your assumption is otherwise correct and this is perfectly fine use of offsetof and static_assert, to detect padding anywhere between member variables.

更好的选择可能是:

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

这也会捕获结构末尾的填充.此外,它使断言更加灵活,以防在代码维护期间更改结构成员.

This also catches padding at the end of the struct. In addition, it makes the assertion more flexible in case the struct members are changed during code maintenance.

这篇关于我们可以使用 static_assert 来检测结构中的填充吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆