【问题标题】:Purpose of atomic structures原子结构的用途
【发布时间】:2018-06-12 18:11:31
【问题描述】:

根据 C11 § 6.5.2.3

Accessing a member of an atomic structure or union object results
in undefined behavior.

这是有道理的,因为您通常无法访问整个结构。仍然为什么_Atomic 也是类型限定符而不仅仅是类型说明符?

换句话说,被限定为_Atomic 的结构的目的是什么?我不能读取或写入其中的任何元素。

#include <stdatomic.h>

struct {
    int x;
} _Atomic foo;

int main(void) {
    foo.x = 42;     // write error
    return foo.x;   // read error
}

foo.x 的两次访问都会导致 GCC/Clang 中出现警告/错误——这完全没问题。 C11 标准。为什么我要限定然后一个结构为_Atomic

【问题讨论】:

    标签: c struct atomic c11


    【解决方案1】:

    您不能访问单个成员,但始终可以访问整个结构。我认为,访问本应成为原子单元的事物的某些部分没有多大意义。

    原子结构的典型用例是两个指针的组合,例如列表的头部和尾部。要操作这样的struct,您必须将当前值从原子复制到临时值,对其进行修改,然后再复制回来。这样您就可以始终保证存储的值在任何时候都是一致的。

    默认情况下,对整个原子 struct 的所有此类操作都具有顺序一致性。

    【讨论】:

    • 有趣,我没想到会有这样的行为。如果我可以原子地访问整个结构,那么我会期望我也可以原子地访问单个元素。对我来说,如果我想修改单个元素,这似乎是一种开销,那么我必须复制整个结构两次。但我可以想象,这种行为更容易在许多架构上指定和保证相同的行为。感谢您的回答!
    【解决方案2】:

    某些实现可能能够保证满足特定标准的结构的原子行为。我不知道在 C11 标准发布之前是否确实存在这样做的任何实现,但它肯定看起来是合理的。如果一个实现有效地支持这样的结构,那么标准要求它们被视为违反约束是相当烦人的。

    如果标准强制或至少建议实现将任何定义原子结构的尝试视为违反约束,他们无法为其提供适当的语义,这将是有帮助的,但无论出于何种原因该标准的作者似乎非常不愿意承认一类程序会被某些实现拒绝但在不拒绝它的实现上定义了行为。一个好的标准应该寻求最大限度地增加属于该类别的有用程序的数量,但该标准倾向于将一些实现将支持而另一些不支持的构造视为未定义行为,让实现支持或不支持它们,但没有提供任何安全的方法来确定它们是否受支持。

    【讨论】:

    • 该标准保证所有符合原子条件的对象是一致的。
    • @JensGustedt:如果程序调用未定义行为,则一致性保证毫无意义。
    • 是的,那又怎样?您在 C 委员会上咆哮的前提是可能存在 “实现无法提供适当语义的原子结构” 。这个前提是完全错误的。所有struct 类型都可以被限定为原子类型,并且该标准为所有这些类型提供了适当的语义。因此,任何 C 标准的实现都不会出现这种情况。
    • @JensGustedt:也许我应该说“为成员访问提供适当的语义”[我认为这是结构语义的一部分]?
    • @JensGustedt:原子的重要之处在于对它们的操作是不可分割的。如果一个结构具有“启用”字段以及一些数据,则可能需要自动设置“启用”字段并加载数据,但在其他时候可能希望能够清除启用字段而不必对其他数据做任何事情。如果“启用”通常为假,则代码可能会从读取启用字段中受益,然后,只有当它为真时,才会读取整个结构(认识到如果“启用”在两次读取之间变为假,则阅读的努力将被浪费)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2011-12-16
    • 2014-09-13
    相关资源
    最近更新 更多