未命名的位域是否具有明确定义的语义?

jxh*_*jxh 11 c language-lawyer c11

以下代码是否保证正常终止并成功终止?

#include <assert.h>

struct foo_s {
    union {
        struct {
            unsigned a : 10;
            unsigned   : 6;
        };
        struct {
            unsigned   : 10;
            unsigned b : 6;
        };
        struct {
            unsigned   : 10;
            unsigned c : 6;
        };
    };
};

int main () {
    struct foo_s f;
    f.a = 0;
    f.b = 1;
    assert(f.a == 0);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在回答不同的问题时,提出了这样的可能性,即在包含未命名的位字段的结构中对指定的位字段的赋值可能导致将任意数据写入这些位.C.11§6.7.2.112陈述:

没有声明符但只有冒号和宽度的位字段声明表示未命名的位字段.

我对此的解读是,未命名的位字段只是一个常规的位字段,唯一的区别是这些位中的值不能直接通过名称获得.是否允许使用"as-if"逻辑推断实现并在这些位中分配任意数据?

Jen*_*edt 5

是的,我认为实现可能会将任意位写入未命名的位字段.我认为脚注126仅仅说明了为什么引入宽度大于0的未命名位域的意图:

未命名的位字段结构成员可用于填充以符合外部强加的布局.

因此,基本上未命名的位字段具有与填充位相同的语义.你不能依赖他们的内容.

当写入相邻的命名位字段时,允许实现基本上忽略未命名的位字段,这a极大地简化了对该字段的处理a.无需读取未命名字段的当前值,并且可以一次性原子地完成写入.就像结构中可能包含的填充位一样.