【发布时间】:2017-04-06 20:46:34
【问题描述】:
我知道我应该使用volatile 关键字来告诉编译器不要优化对变量的内存读写。我也知道在大多数情况下它是should only be used to talk to non-C++ memory。
但是,我想知道在持有指向某个本地(堆栈)变量的指针时是否必须使用volatile。
例如:
//global or member variable
/* volatile? */bool* p_stop;
void worker()
{
/* volatile? */ bool stop = false;
p_stop = &stop;
while(!stop)
{
//Do some work
//No usage of "stop" or p_stop" here
}
}
void stop_worker()
{
*p_stop = true;
}
在我看来,具有某种优化级别的编译器可能会看到 stop 是一个局部变量,它永远不会更改,并且可以用 while(true) 替换 while(!stop),从而在什么都不做的情况下更改 *p_stop。
那么,在这种情况下是否需要将指针标记为 volatile?
P.S:请不要告诉我为什么不使用它,使用此 hack 的真实代码是出于(复杂到难以解释的)原因。
编辑:
-
我没有提到这两个函数在不同的线程上运行。
worker()是第一个线程的函数,应该使用p_stop指针从另一个线程停止。 -
我不想知道有什么更好的方法来解决这种黑客行为背后的真正原因。我只是想知道这是否是 C++ 中定义的\未定义的行为(11),以及这是否依赖于编译器\平台\等。到目前为止,我看到@Puppy 说每个人都错了,而且这是错误的,但没有参考表明这一点的特定标准。
我知道你们中的一些人对“不要教训我”部分感到冒犯,但请坚持真正的问题 - 我应该使用 volatile 还是不使用?或者这是UB?如果可以,请通过提供完整的答案帮助我(和其他人)学习新知识。
【问题讨论】:
-
对于线程同步,使用
std::atomic。volatile与线程无关。 -
@ZivS:所以,现在我们讨论的是不同的线程。是的,如果
stop可以被不同的线程改变,它应该是volatile。 -
不,真的不应该是
volatile,应该是atomic,这是完全不同的东西。 -
投反对票的人 - 请解释你这样做的原因
-
另外,您反复说“请不要教训我,我知道 bla bla”,然后说“OP 怎么知道这是 UB?”。大声笑
标签: c++ compiler-optimization volatile