C99 中的易失性语义
我对正在编写的一些低级代码有疑问,我需要将对象用作易失性的,但这不一定是我希望将类型声明为易失性的(出于可重用性原因)。 然而,我可以定义指向结构的限定变体的指针,如以下片段所示。
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 struct x {
struct y * volatile bar;
};
或:
volatile struct x {
volatile struct y * volatile bar;
};
我已经通读了 C 标准,对此还不是很清楚,我可以轻松地以多种方式解释该措辞。
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). 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:
volatile struct x {
volatile int x;
};
since volatile apply to all struct members. 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:
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在你的例子中你
得到一个易失性指针,仅此而已,易失性并没有扩展到对象。
扩展我的答案 易失性是一个宽松的原子,这意味着访问是原子的,但指令不是。 因此,您无法线程安全地递增或递减易失性,因此您无法使用易失性指针进行交互,只能使用存储/加载(分配)操作。
对于 int 或其他数字也是如此,并且 volatile 也不适用于浮点数,因为它们是在 FPU 管道中处理的,而不是在 CPU 中处理的。 总而言之,易失性并不是很有用,但微软的编译器会自动在易失性周围放置指令保护,使它们成为真正的原子值,但这不是标准的一部分。
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. 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.
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. 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.
仔细阅读这里的标准,似乎指针是易失性的,但不是结构本身的实际内容。 我从给出的示例中解释了这一点,
const t * volatile p
(位于链接底部)。 然而,措辞很模糊,但我认为这将是一个类似的例子:请注意,我还没有尝试过这个,所以我可能完全不正确......这只是我从粗略的通读中收集到的内容标准的。
此外,cdecl 确实消除了一些模糊之处。 例如:
然而:
在一个实例中,该结构是易失性的。 另一方面,指针。
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). The wording, however, is vague, but I think that this would be a similar example: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. For example:
Whereas:
In one instance, the struct is volatile. In the other, the pointer.