_工会的原子成员是个好主意吗?

问题描述 投票:0回答:1

我在联合内部使用 _Atomic 整数,例如:

union dedup_option_seq {
    struct {
        uint32_t seq :DEDUP_SHIFT;  // enough bits for seq
        uint32_t not_empty :1;      // inverted so that zero is empty
    };
    _Atomic uint32_t value;
};

然后我可以愉快地使用

&foo.value
作为
atomic_...()
函数中的参数。

我可以使用语法设置联合的值:

union dedup_option_seq foo = {
    .seq = 42,
    .not_empty = 1
};

一切都工作得很好,但是当我与 _Atomic 成员一起使用联合体时,我是否会导致任何未定义的行为或其他问题?

c union atomic compare-and-swap
1个回答
2
投票

一切都工作得很好,但是当我与 _Atomic 成员一起使用联合体时,我是否会导致任何未定义的行为或其他问题?

C 允许您读回联合体中与上次设置的成员不同的成员。这在 C 中是可以的(但在 C++ 中不行)。 C 不会根据所涉及类型的限定符(例如

_Atomic
)来限制这一点,因此这不是直接的问题。

但是,

    不保证
  • _Atomic
    类型与其对应的非
    _Atomic
    类型具有相同的大小或表示形式,并且

  • struct
    中位域的布局比您想象的要少得多。

在这些之间,C 允许你的例子

  • value
    的表示可能不会与
    seq
    not_empty
    的整个表示重叠。在不这样做的实现中,您尝试通过
    value
    以原子方式操作这些位将不会达到您期望的效果。

  • 即使

    value
    确实与整个
    seq
    not_empty
    重叠,后两者的某些位也可能不对应于前者的值位。在这种情况下,您尝试通过
    value
    以原子方式操作这些位可能不会达到您预期的效果。

  • 分配给

    seq
    和/或
    not_empty
    可能会导致
    value
    包含陷阱表示,即使普通
    uint32_t
    没有任何陷阱表示。在这种情况的实现中,尝试通过
    value
    以原子方式操作这些位可能会导致陷阱,可能导致程序崩溃。这种情况是否发生以及何时发生可能取决于数据。

此外,通过联盟的其他成员以非原子方式操作

_Atomic
对象
value
似乎令人担忧。至少,此类操作不享有直接操作
value
所提供的任何原子性保证。

那么这里是否存在未定义的行为?很难说。肯定存在语言规范没有直接解决的行为问题。其中部分或全部可能比未定义更好地描述为未指定,但如果您需要您的程序在不同的 C 实现上可重复地产生相同的结果,则前者并不比后者好多少。

© www.soinside.com 2019 - 2024. All rights reserved.