提问人:fadedbee 提问时间:10/27/2023 最后编辑:fadedbee 更新时间:10/27/2023 访问量:62
_Atomic工会成员是个好主意吗?
Are _Atomic members of unions a good idea?
问:
我在联合内部使用_Atomic整数,例如:
union dedup_option_seq {
struct {
uint32_t seq :18; // 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成员的工会时,我是否会导致任何未定义的行为或其他问题?
答:
一切都很好,但是在使用_Atomic成员的工会时,我是否会导致任何未定义的行为或其他问题?
C 允许您读回与上次设置的联合不同的成员。这在 C 中是可以的(但在 C++ 中不是)。C 不会根据所涉及类型的限定符(例如)对其进行限制,因此这不是直接问题。_Atomic
然而
_Atomic
不保证类型具有与其相应的非对应项相同的大小或表示形式,并且_Atomic
A 中位域的布局比您想象的要少得多。
struct
在这些之间,C 允许你的例子
的表示形式可能不会与 和 的全部表示重叠。在没有实现的情况下,您尝试以原子方式操作这些位不会产生预期的效果。
value
seq
not_empty
value
即使 和 的整个 and 重叠,后两者的某些位也可能与前者的值位不对应。在这种情况下,您尝试以原子方式操纵这些位可能不会产生您预期的效果。
value
seq
not_empty
value
赋值给和/或可能导致包含陷阱表示,即使普通没有任何陷阱表示。在可能出现这种情况的实现中,尝试以原子方式操作这些位可能会导致陷阱,从而可能使程序崩溃。是否以及何时发生可能取决于数据。
seq
not_empty
value
uint32_t
value
此外,通过联盟的其他成员以非原子方式操纵物体似乎令人担忧。至少,这种操作不享有操纵直接提供的任何原子性保证。_Atomic
value
value
那么这里是否存在未定义的行为?很难说。肯定存在有关语言规范未直接解决的行为的问题。其中一些或全部可能更适合描述为未指定而不是未定义,但如果您要求程序在不同的 C 实现上可重复地产生相同的结果,那么前者并不比后者好多少。
评论
sizeof(union dedup_option_seq) == sizeof(uint32_t) == sizeof(_Atomic uint32_t)
.seq
.not_empty
.value
评论
std::atomic_ref
,所以如果你仔细做所有事情,这应该很好。DEDUP_SHIFT
union
atomic_ref
atomic<16byte struct>.member
seq
not_empty