如果我有一个C++方法声明如下:
class A
{
public:
double getPrice() volatile;
};
Run Code Online (Sandbox Code Playgroud)
volatile这里有什么代表?您可能会感兴趣的这种由安德烈Alexandrescu的多布斯博士的文章.我曾是 :)
编辑: 那篇文章写了一段时间,现在似乎社区已经开始了.香草萨特有这说这个.谢谢Iain(和Herb!)
mlimber他指出,Andrei在这里有一篇后续文章,他继续提倡使用不稳定的正确性作为检测支持POSIX类互斥体的系统上的竞争条件的有用工具.
met*_*tal 13
您可能熟悉const方法和const-correctness(参见Sutter和Alexandrescu 在C++编码标准中的"第15项 - 主动使用const" ),并volatile以类似但略有不同的方式工作,以产生可能被称为"volatile-correctness"的东西. ".
比如const,volatile是一个类型修饰符.当附加到成员函数时,如示例中所示,修饰符(或两者!)表示调用该方法的对象必须具有或可转换为该类型.
考虑:
struct A
{
void f();
void cf() const;
void vf() volatile;
void cvf() const volatile;
// ...
};
void foo( A& a, const A& ca, volatile A& va, const volatile A& cva )
{
a.f(); // Ok
a.cf(); // Ok: Can convert non-const obj to const obj
a.vf(); // Ok: Can convert non-volatile obj to volatile obj
a.cvf(); // Ok: Can convert non-cv obj to cv obj
ca.f(); // Error: can't call non-const method on const obj
ca.cf(); // Ok
ca.vf(); // Error: can't call non-const method on const obj
ca.cvf(); // Ok: Can convert
va.f(); // Error: can't call non-volatile method on volatile obj
va.cf(); // Error: can't call non-volatile method on volatile obj
va.vf(); // Ok
va.cvf(); // Ok: Can convert
cva.f(); // Error: can't call non-cv method on cv obj
cva.cf(); // Error: can't call non-cv method on cv obj
cva.vf(); // Error: can't call non-cv method on cv obj
cva.cvf(); // Ok
}
Run Code Online (Sandbox Code Playgroud)
请注意,这些是编译时错误,而不是运行时错误,这就是它的潜在用途.
正确性可以防止编译时出现意外错误,并使代码"更容易理解,跟踪和推理"(Sutter和Alexandrescu).挥发正确性同样可以发挥作用,但要少得多使用(注意,const_cast在C++中可以抛弃const,volatile或者const volatile,而不是调用它cv_cast或类似的,它之后的命名const孤单,因为这是更为普遍用于铸造仅有const).
例如,在"volatile - Multithreaded Programmer's Best Friend"中,Andrei Alexandrescu给出了一些示例,说明如何使用它来让编译器自动检测多线程代码中的竞争条件.关于类型修饰符的工作方式,它有很多解释,但在随后的专栏中也可以看到他的后续评论.
更新:
请注意,C++ 11改变了它的含义const.因此,Sutter说:" const现在确实意味着'只读'或安全地同时读取' - 要么真正的物理/按位const,要么内部同步,以便任何实际写入与任何可能的并发const访问同步,因此呼叫者无法分辨区别."
在其他地方,他指出虽然C++ 11添加了并发原语,volatile但仍然不是其中之一:"C++ volatile变量(在C#和Java等语言中没有模拟)总是超出了本文和任何其他文章的范围.内存模型和同步.这是因为C++ volatile变量根本不是关于线程或通信的,也不与这些事物进行交互.而是应该将C++ volatile变量视为不同语言的门户 - 一个内存根据定义,该位置不遵守语言的内存模型,因为该内存位置由硬件访问(例如,由子卡写入),具有多个地址,或者在其他方面是"奇怪的"且超出语言.所以C++ volatile变量通常是关于同步的每个指南的一个例外,因为它总是使用常规工具(互斥,原子等)本质上是"活泼的"和不同步的,并且通常存在于所有的范围之外 语言和编译器的错误,包括它们通常无法由编译器优化....有关更多讨论,请参阅我的文章' volatile vs. volatile.'"
它是一个volatile成员,就像const成员只能在const对象上调用一样,只能在volatile对象上调用.
什么用途?好吧,全局易变性很少使用(经常被误解为适用于MT编程,在C++中并非如此,例如见http://www.drdobbs.com/high-performance-computing/212701484)和volatile类对象的用处更少.
IIRC A. Alexandrescu建议使用对volatile对象进行的类型检查来静态地确保一些对MT编程有用的属性(比如在调用成员函数之前已经进行了锁定).可悲的是,我没有找到这篇文章.(这是:http://www.drdobbs.com/184403766)
编辑:添加评论中的链接(它们也在问题中添加).
在成员函数(唯一具有cv限定词的函数)中,const或volatile有效修改this指针。因此,就像const成员函数只能像通过const指针访问对象一样,volatile成员函数也只能像通过volatile指针访问对象一样。
非正式的含义volatile是,对象可能会由于程序外部的情况(例如内存映射的I / O或共享内存)而发生更改。确切的含义是,任何对volatile数据的访问都必须在代码中写入时实际上在进行,并且不得相对于其他volatile访问或I / O操作按顺序进行优化或更改。
这意味着在volatile成员函数中与对象有关的所有操作必须按编写的顺序进行。
此外,volatile成员函数只能调用其他volatile(或const volatile)成员函数。
至于它的用途...坦白说,我现在想不出一个好用途。 volatile对于某些数据对象至关重要,例如指向I / O寄存器的指针,但我想不出为什么volatile成员函数会有用。
| 归档时间: |
|
| 查看次数: |
6359 次 |
| 最近记录: |