gpt4 book ai didi

c++ - 这里需要 volatile 吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:32:06 26 4
gpt4 key购买 nike

在 Johannes 的宝贵回答后编辑并完善了我的问题

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 本身是 volatile 的,那么是否允许编译器假设 b 在循环中不会改变,即使 b 不是 volatile 的?

请避免针对这段代码的风格发表评论和回答,这不是真实世界的例子,这是一个实验性的理论问题。非常欢迎评论和回答,除了回答我的问题外,还更详细地解决了您认为我误解了的 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();
}
}

这两个程序之间是否存在主要区别。如果是,有什么区别?

最佳答案

The question is, in this case pf is itself volatile, so is the compiler allowed to assume that b won't change in the loop even if b is not volatile?

它不能,因为你说 pf 可能会被其他线程更改,如果 pf 是,这会间接更改 b然后由 while 循环调用。所以虽然理论上不需要正常读取b,但实际上必须读取它以确定是否应该短路(当b变为false 它不能再次读取 vb


第二部分的答案

在这种情况下 pf 不再是 volatile,所以编译器可以摆脱它并看到 f1 有一个空体和 f2b 设置为 false。它可以优化 main 如下

int main()
{
// threads here (which you say can only change "vb")

while(vb)
{
int x;
std::cin >> x;
if(x != 0)
break;
}
}

对旧版本的回答

允许编译器优化循环的一个条件是循环不访问或修改任何 volatile 对象(参见 n3126 中的 [stmt.iter]p5)。你在这里这样做,所以它不能优化循环。在 C++03 中,甚至不允许编译器优化该循环的非 volatile 版本(但编译器还是这样做了)。

请注意,另一个能够优化它的条件是循环不包含同步或原子操作。在多线程程序中,无论如何都应该存在这种情况。因此,即使您摆脱了 volatile,如果您的程序编码正确,我认为编译器也无法完全优化它。

关于c++ - 这里需要 volatile 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3949974/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com