【问题标题】:Volatile Struct Semantics易失结构语义
【发布时间】:2011-01-03 21:54:49
【问题描述】:

将结构类型变量的实例声明为 volatile 是否足够(如果在可重入代码中访问其字段),还是必须将结构的特定字段声明为 volatile?

措辞不同,以下之间的语义差异(如果有的话)是什么:

typdef struct {
  uint8_t bar;
} foo_t;

volatile foo_t foo_inst;

typedef struct{
  volatile uint8_t bar;
} foo_t;

foo_t foo_inst;

我认识到将指针类型的变量声明为 volatile(例如 volatile uint8_t * foo)只会通知编译器 foo 指向的地址可能会改变,而不会声明 foo 指向的值。我不清楚类比是否适用于结构类型的变量。

【问题讨论】:

  • 在 C 中,两个版本之间没有区别,但是,在 C++ 中,它们是不同的,如下例所示:godbolt.org/z/fYhzMKqjj 您可以自己尝试。

标签: c struct volatile


【解决方案1】:

在您的示例中,两者是相同的。但问题围绕着指针。

首先,volatile uint8_t *foo; 告诉编译器指向的内存是易失的。如果要将指针本身标记为 volatile,则需要执行 uint8_t * volatile foo;

这就是将结构标记为 volatile 与标记单个字段之间的主要区别之处。如果你有:

typedef struct
{
    uint8_t *field;
} foo;

volatile foo f;

这就像:

typedef struct
{
    uint8_t * volatile field;
} foo;

不喜欢:

typedef struct
{
    volatile uint8_t *field;
} foo;

【讨论】:

  • 如果字段是uint8_t field[10],当您将结构标记为 volatile 时,是标记为 volatile 的基础数据还是指向标记为 volatile 的字段的“有效”指针?
  • 底层数据是易变的。需要考虑的一件事是“有效”指针是不可修改的(它始终是第一个元素的地址),因此 volatile 对此没有任何意义。
  • 可以将结构definition 标记为易失性吗?还是必须只保留 typedef 或实例变量?
【解决方案2】:

如果你用 volatile 声明一个结构,那么它的所有成员也将是 volatile

【讨论】:

  • 在侧边栏上,const 也是如此
猜你喜欢
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多