我在联合体中使用_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成员的联合时,我会导致任何未定义的行为或其他问题吗?
1条答案
按热度按时间7y4bm7vi1#
这一切都工作得很好,但是当使用带有_Atomic成员的联合时,我会导致任何未定义的行为或其他问题吗?
C允许你读回一个联合体中不同于上次设置的成员。这在C中是可以的(但在C++中不行)。C不会根据所涉及类型的限定符(如
_Atomic
)来限制这一点,所以这不是一个直接的问题。然而,在这方面,
_Atomic
类型不能保证与对应的非_Atomic
类型具有相同的大小或表示,struct
中位域的布局比您想象的要少得多。在这两者之间,C允许你的例子,
value
的表示可能不会与seq
和not_empty
的表示全部重叠。在不重叠的实现中,您尝试通过value
原子地操作这些位不会产生预期的效果。value
与seq
和not_empty
完全重叠,后两者的某些位可能与前者的值位不对应。在这种情况下,您尝试通过value
原子地操作这些位可能不会产生预期的效果。uint32_t
没有任何陷阱表示,但将seq
和/或not_empty
转换为value
可能会导致value
包含陷阱表示。在可能出现这种情况的实现中,尝试通过value
原子地操作这些位可能会导致陷阱,可能会导致程序崩溃。是否以及何时发生可能取决于数据。此外,通过联合体的其他成员非原子地操作
_Atomic
对象value
似乎是令人担忧的。至少,这样的操作不享受直接操作value
所提供的任何原子性保证。那么这里是否存在未定义的行为呢?很难说。关于语言规范没有直接处理的行为,肯定有一些问题。其中一些或全部可能更好地描述为未定义而不是未定义,但如果你要求你的程序在不同的C实现上可重复地产生相同的结果,前者并不比后者好多少。