在C23标准发布之前,对原子变量进行复合赋值是否仍然能保证原子性?

编程语言 2026-07-11

在C23标准出现之前的标准中,有如下表述,引用N3047 The atomic_fetch and modify generic functions §7.17.7.5 p5

注意 The operation of the atomic_fetch and modify generic functions are nearly equivalent to the operation of the corresponding op= compound assignment operators. The only differences are that the compound assignment operators are not guaranteed to operate atomically, and the value yielded by a compound assignment operator is the updated value of the object, whereas the value returned by the atomic_fetch and modify generic functions is the previous value of the atomic object.

这似乎与 Compound assignment §6.5.16.2 p4 相矛盾:

A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics.

§7.17.7.5 p5在 DR 486 中被引用,被 N2389 (1.3.) 认为是错误的,并在C23标准中被彻底移除。

因为这似乎是标准中的一个缺陷,那么在较旧的编译器或处于pre-C23模式的编译器中,对原子变量进行的复合赋值是否仍然可以被认为是原子性的?

解决方案

§7.17.7.5 p5的标题是“Note”,而在所有ISO标准中,注释不是规范性要求。因此,并不应有任何实现者用该段来判断复合赋值运算是否应原子。

另一方面,§6.5.16.2 p4 规范性的,并明确指出,当对原子类型应用复合赋值运算符时,其运算是原子的。所以实现者应当如此实现。

我认为 §7.17.7.5 p5的作者想要将其与“一般”的复合赋值运算符作比较,应用于并不一定原子化的类型,这可能被认为对读者更易理解。同样,这不是用于定义 atomic_fetch_* 的行为的方式(因为该段是非规范性的),而是帮助理解。效果并不十分成功,但我预计实现者在上下文中仍然能够理解其含义,不会感到困惑。

当然,在主要实现中,当复合赋值运算符作用于原子类型时,确实从C11引入原子类型以来就表现为原子读-修改-写操作。这一点非常值得依赖(当然,像往常一样,会存在漏洞的可能)。


尽管如此,我仍更倾向于在可能的情况下使用 atomic_fetch_* 函数:它们让原子运算更加直观,并且允许指定内存序。同时,通常获取对象的旧值比新值更有用。

还有一些奇怪的情况,复合赋值允许执行一个原子操作,但没有对应的 atomic_fetch_* 函数:*=%=<<= 等;但它们不太可能经常需要。无论如何,大多数体系结构不会为这些操作提供机器指令,因此通常会用类似比较并交换循环来实现;因此你不妨在源代码中显式地编写这样的循环。这也有一个好处,就是可以选择内存序。它也会使移植到不提供此类操作的 std::atomic 类型的C++更容易。

(原理上,编译器在LL/SC机器上可以通过在LL/SC内部实际执行该运算来做得更好,但即使是最先进的C 编译器目前也不会这么做:https://godbolt.org/z/sa47KnYvT。)

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章