简体   繁体   English

C99中的易失性语义

[英]Volatile semantics in C99

I have an issue with some low level code I am writing, I need to use objects as volatile, but it is not necessarily so that I want the types to be declared as volatile (for reusability reasons). 我遇到了一些我正在编写的低级代码的问题,我需要将对象用作volatile,但不一定是因为我希望将类型声明为volatile(出于可重用性的原因)。 I can however define pointer to a qualified variant of a structure as detailed in the following segment. 但是,我可以定义指向结构的限定变体的指针,如以下段中所述。

struct x {
  int bar;
};

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

Now foo is effectively a pointer to an object of the type: 现在foo实际上是指向该类型对象的指针:

volatile struct x {
  volatile int x;
};

since volatile apply to all struct members. 因为volatile适用于所有struct成员。 Now my question is when an object contain a pointer to another object, how is the volatileness applied? 现在我的问题是当一个对象包含指向另一个对象的指针时,如何应用波动性?

struct x {
  struct y *bar;
};

Will a pointer to a volatile instance of x then then treat this as: 指向x的volatile实例的指针然后将其视为:

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

or as: 或作为:

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

I've read through the C standard, and it is not very clear regarding this, and I can easily interprete the wording in multiple ways. 我已经阅读了C标准,对此并不是很清楚,我可以通过多种方式轻松解释这些措辞。

In your example you get a volatile pointer, that's all, the volatility isn't extended to the object. 在你的例子中,你得到一个易失性指针,就是这样,波动性不会扩展到对象。

Expanding on my answer volatile is a relaxed atomic, that means access is atomic, but instructions won't be. 扩展我的答案volatile是一个轻松的原子,这意味着访问是原子的,但指令不会。 So you can't threadsafely increment or decrement a volatile, so you can't use a volatile pointer for interation, only store/load (assigment) operations. 因此,您无法线程安全地增加或减少volatile,因此您不能使用volatile指针进行交互,只能使用store / load(assigment)操作。 Same goes for an int or another number, and volatile also won't work with floats because they are processed in the FPU pipeline, not the CPU. 对于int或其他数字也是如此,volatile也不能用于浮点数,因为它们是在FPU管道中处理的,而不是CPU。 All in all volatile aren't too useful, but Microsoft's compilers automatically place instruction guards around volatiles, making them true atomic values, but that's not part of the standard. 总而言之,volatile并不太有用,但微软的编译器会自动将指令保护在挥发物周围,使其成为真正的原子价值,但这不是标准的一部分。

Reading through the standard here , it seems as though the pointer is volatile, but not the actual contents of the struct itself. 通过这里的标准阅读,似乎指针是易变的,但不是结构本身的实际内容。 I interpreted that from the example given, const t * volatile p (at the bottom of the link). 我从给出的例子中解释了const t * volatile p (在链接的底部)。 The wording, however, is vague, but I think that this would be a similar example: 然而,措辞含糊不清,但我认为这是一个类似的例子:

struct foo {
    int bar;
};

struct foo *volatile x;

Note that I have not tried this, so I may be wildly incorrect... it is simply what I've gathered from a cursory read-through of the standard. 请注意,我没有尝试过这个,所以我可能会非常不正确...这只是我从粗略的标准阅读中收集的内容。

Furthermore, cdecl does clear up some of the vagueness. 此外,cdecl确实清除了一些模糊性。 For example: 例如:

cdecl> explain volatile struct x* foo cdecl>解释volatile struct x* foo
declare foo as pointer to volatile struct x 将foo声明为volatile x的指针

Whereas: 鉴于:

cdecl> explain struct x* volatile foo cdecl>解释struct x* volatile foo
declare foo as volatile pointer to struct x 将foo声明为struct x的volatile指针

In one instance, the struct is volatile. 在一个实例中,结构是易失性的。 In the other, the pointer. 在另一个,指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM