【问题标题】:Volatile semantics in C99C99 中的易失语义
【发布时间】:2010-11-02 03:39:56
【问题描述】:

我在编写一些低级代码时遇到问题,我需要将对象用作易失性对象,但这并不一定是我希望将类型声明为易失性(出于可重用性原因)。但是,我可以定义指向结构的合格变体的指针,如下节所述。

struct x {
  int bar;
};

struct x foobar;
...
volatile struct x *foo = &foobar;

现在 foo 实际上是一个指向该类型对象的指针:

volatile struct x {
  volatile int x;
};

因为 volatile 适用于所有结构成员。现在我的问题是当一个对象包含指向另一个对象的指针时,如何应用易失性?

struct x {
  struct y *bar;
};

将一个指向 x 的 volatile 实例的指针然后将其视为:

volatile struct x {
  struct y * volatile bar;
};

或作为:

volatile struct x {
  volatile struct y * volatile bar;
};

我通读了 C 标准,对此不是很清楚,我可以很容易地从多种方式解释措辞。

【问题讨论】:

    标签: c pointers c99 volatile


    【解决方案1】:

    在您的示例中,您 获取一个 volatile 指针,仅此而已,volatile 没有扩展到对象。

    扩展我的答案 volatile 是一个轻松的原子,这意味着访问是原子的,但指令不会。因此,您不能线程安全地递增或递减 volatile,因此您不能使用 volatile 指针进行交互,只能使用存储/加载(分配)操作。 对于 int 或其他数字也是如此,并且 volatile 也不适用于浮点数,因为它们是在 FPU 管道中处理的,而不是在 CPU 中处理的。总而言之 volatile 并不太有用,但微软的编译器会自动在 volatile 周围放置指令保护,使它们成为真正的原子值,但这不是标准的一部分。

    【讨论】:

    • netrino.com/node/80 似乎支持这个想法。我从来没有读过vololitile。好东西。
    • “volatile 不太有用”:不了解 PC 软件,但在嵌入式系统中,它们对于声明可以在中断中更改的硬件寄存器或变量至关重要。
    • 非常好!自从我上一个嵌入式项目以来已经有几年了,所以我忘记了。无论如何,因为它是用于加载和存储的。在 PC 上,大多数中断很容易被 OS api 抽象掉。
    • @SteveMelnikoff:在嵌入式系统中,经常需要保证对地址已暴露给外界的所有对象的操作按照volatile操作的顺序进行,但因为并非所有应用程序都需要这样的语义,C 标准并不强制要求它们用于所有实现。不幸的是,据我所知,gcc 和 clang 提供的使它们以这种方式工作的唯一选项是-o0,它禁用了所有优化。
    【解决方案2】:

    阅读标准here,似乎指针 是易变的,但不是结构本身的实际内容。我从给出的示例中解释了这一点,const t * volatile p(在链接的底部)。然而,措辞含糊不清,但我认为这将是一个类似的例子:

    struct foo {
        int bar;
    };
    
    struct foo *volatile x;
    

    请注意,我没有尝试过这个,所以我可能非常不正确......这只是我从粗略阅读标准中收集的内容。

    此外,cdecl 确实消除了一些模糊性。例如:

    cdecl> 解释volatile struct x* foo
    将 foo 声明为指向 volatile struct x 的指针

    鉴于:

    cdecl> 解释struct x* volatile foo
    将 foo 声明为指向 struct x 的 volatile 指针

    在一种情况下,结构是易失的。另一个是指针。

    【讨论】:

    • 所以你不能只做 volatile struct x* volatile foo;对于易失性指针和结构?
    • @earlz:是的。确切地。 volatile struct x* volatile foo 是指向 volatile struct x 的 volatile 指针。
    猜你喜欢
    • 1970-01-01
    • 2011-01-03
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多