给定以下课程:
class MyClass {
public:
int value() const {
return value_;
}
private:
volatile int value_;
};
value() 成员函数是否也必须标记为 volatile 以避免被优化,或者它是否可以编写?谢谢。
给定以下课程:
class MyClass {
public:
int value() const {
return value_;
}
private:
volatile int value_;
};
value() 成员函数是否也必须标记为 volatile 以避免被优化,或者它是否可以编写?谢谢。
它与工作方式完全相似const
。
如果您有一个const
对象,则只有标记的成员函数const
是可调用的。
所以...
如果您有一个volatile
对象,则只有标记的成员函数volatile
是可调用的。
只要对象本身不是volatile
,函数是否是没有区别的。
但是,请记住这与多线程无关volatile
,它不会帮助您编写线程安全的代码。对于与并发相关的任何事情,它都是错误的工具。
value() 成员函数是否也必须标记为 volatile 以避免被优化,或者它是否可以编写?
将成员函数标记为 volatile 不会影响它是否被优化掉。写的很好。
担心的是我是否有 MyClass c;然后调用 c.value(); 有几次,编译器可能认为 c.value() 将返回相同的值(即使它可能已经改变了..)
听起来您想要了解原子变量。看看std::atomic。
如果你真的想了解 volatile,请阅读这篇论文:http ://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf
担心的是我是否有 MyClass c;然后调用 c.value(); 有几次,编译器可能认为 c.value() 将返回相同的值(即使它可能已经改变了..)
在单独的编译模型中,编译器看不到函数的内部,它不能假设它们不会有副作用([*]),因此不能删除对函数的不同调用。如果编译器正在查看函数的定义并内联代码,那么它会看到该成员是volatile
,因此也无法对其进行优化。
[*] 一些编译器(即 gcc)具有特殊的属性,您可以使用这些属性告诉它一个函数是纯函数(即它没有副作用,并且输出仅取决于提供的参数)以允许对一个函数进行多次调用优化了,例如在这个循环中:
const char* lit = "Literal";
int sum = 0;
for ( int i = 0; i < strlen(lit); ++i ) {
sum += lit[i];
}
因为strlen
在库中被标记为pure,所以编译器会缓存该值并将循环转换为:
const char* lit = "Literal";
int sum = 0;
int __len = strlen(lit);
for ( int i = 0; i < __len; ++i ) {
sum += lit[i];
}
但是库必须明确告诉编译器这是可以做到的。如果没有属性形式的额外信息,则无法假设任何内容,并且strlen
必须在循环的每次迭代中调用该函数。
常量和易失性成员函数(仅限 C++)
可以为常量和非常量对象调用使用 const 限定符声明的成员函数。非常量成员函数只能为非常量对象调用。类似地,可以为 volatile 和 nonvolatile 对象调用使用 volatile 限定符声明的成员函数。只能为非易失性对象调用非易失性成员函数。