C++ 这里需要挥发油吗?
根据约翰尼斯的宝贵回答,编辑并完善了我的问题C++ 这里需要挥发油吗?,c++,volatile,C++,Volatile,根据约翰尼斯的宝贵回答,编辑并完善了我的问题 bool b = true; volatile bool vb = true; void f1() { } void f2() { b = false; } void(* volatile pf)() = &f1; //a volatile pointer to function int main() { //different threads start here, some of which may change pf
bool b = true;
volatile bool vb = true;
void f1() { }
void f2() { b = false; }
void(* volatile pf)() = &f1; //a volatile pointer to function
int main()
{
//different threads start here, some of which may change pf
while(b && vb)
{
pf();
}
}
所以,让我们暂时忘记同步。问题是b是否必须声明为不稳定的。我已经阅读了标准,并大致了解了volatile语义的正式定义(我甚至几乎能理解它们,单词几乎是关键)。不过我们还是随便说说吧。如果编译器在循环中发现b无法更改,那么除非b是易失性的,否则它可以对其进行优化,并假定它等同于while(vb)
。问题是,在这种情况下pf本身是易失性的,那么编译器是否可以假设即使b不是易失性的,b也不会在循环中改变
请不要评论和回答这段代码的风格,这不是一个真实的例子,这是一个实验性的理论问题。
除了回答我的问题外,您认为我误解了volatile的语义,我们非常欢迎您的评论和回答
我希望我的问题是清楚的。短暂性脑缺血发作
再次编辑:这个怎么样
bool b = true;
volatile bool vb = true;
void f1() {}
void f2() {b = false;}
void (*pf) () = &f1;
#include <iosrteam>
int main()
{
//threads here
while(b && vb)
{
int x;
std::cin >> x;
if(x == 0)
pf = &f1;
else
pf = &f2;
pf();
}
}
bool b=true;
volatile bool vb=true;
void f1(){}
void f2(){b=false;}
无效(*pf)(=&f1;
#包括
int main()
{
//这里的线程
while(b&vb)
{
int x;
标准:cin>>x;
如果(x==0)
pf=&f1;
其他的
pf=&f2;
pf();
}
}
这两个项目之间有主要区别吗。如果是,有什么区别
问题是,在这种情况下pf本身是易失性的,那么编译器是否可以假设即使b不是易失性的,b也不会在循环中改变
它不能,因为您说其他线程可能会更改pf
,如果while循环调用pf
,这会间接更改b
。因此,虽然理论上不要求正常读取b
,但实际上必须读取它以确定是否应短路(当b
变为false
时,它不得再次读取vb
)
对第二部分的回答 在这种情况下,
pf
不再是易失性的,因此编译器可以去掉它,并看到f1
有一个空的主体,f2
将b
设置为false。它可以优化main
,如下所示
int main()
{
// threads here (which you say can only change "vb")
while(vb)
{
int x;
std::cin >> x;
if(x != 0)
break;
}
}
对旧版本的回答 允许编译器优化循环的一个条件是循环不访问或修改任何易失性对象(请参阅n3126中的[stmt.iter]p5)。你在这里这样做,所以它不能优化循环。在C++03中,编译器甚至不能优化循环的非易失性版本(但编译器还是这样做了)
请注意,能够优化它的另一个条件是循环不包含同步或原子操作。但在多线程程序中,无论如何都应该存在这样的问题。因此,即使你摆脱了那种
易失性
,如果你的程序编码正确,我也不认为编译器可以完全优化它。易失性只会伤害到你,如果你认为你可以从一种无法完成的优化中获益,或者如果它传达了一些不真实的信息
在您的例子中,您说过这些变量可以被其他线程更改。在阅读代码时,当我看到volatile时,这是我的假设,所以从维护人员的角度来看,这很好——它给了我额外的信息(这是真的)
我不知道这些优化是否值得尝试挽救,因为您说过这不是真正的代码,但如果不是,那么就没有任何理由不使用volatile
不使用volatile会导致不正确的行为,因为优化正在改变代码的含义
我担心对编译器的标准和行为的细节进行编码,因为这类事情可能会发生变化,即使它们不会发生变化,代码也会发生变化(这可能会影响编译器)——因此,除非您在这一特定代码上寻求微优化改进,我就不这么说了。 < P>在当前的C++标准中,在
b
。因此,volatile
与此无关
将其扩展到您的第一个实际情况,并允许编译器进行整个程序优化,因为pf
是不稳定的,编译器仍然不知道它将指向什么(它甚至不能假设它是f1
或f2
!),因此,同样不能对函数指针调用中未修改的内容做出任何假设,因此volatile
onb
仍然是不相关的
您的第二种情况实际上更简单--vb
,因为它是一条红鲱鱼。如果消除了这一点,您可以看到,即使在完全单线程语义中,函数指针调用也可能修改b
。您没有使用未定义的行为执行任何操作,因此程序必须在没有volatile
的情况下正确运行--请记住,如果您没有考虑使用外部线程调整的情况,volatile
是不可操作的。因此,没有