11

下面的代码是否保证正常且成功终止?

#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;
}

在回答不同的问题时,提出了在还包含未命名位字段的结构中分配给命名位字段的可能性可能会导致将任意数据写入这些位。C.11 §6.7.2.1 ¶12 状态:

没有声明符但只有冒号和宽度的位域声明表示未命名的位域。

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

4

1 回答 1

5

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

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

所以基本上未命名的位域与填充位具有相同的语义。你不能依赖他们的内容。

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

于 2013-09-06T06:49:59.527 回答