- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我知道我应该使用 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(!stop)
替换while(true)
并因此更改 *p_stop
而什么都不做。
那么,在这种情况下是否需要将指针标记为 volatile?
P.S:请不要教我为什么不使用这个,使用这个 hack 的真实代码是出于(复杂到无法解释的)原因这样做的。
编辑:
我没有提到这两个函数在不同的线程上运行。worker()
是第一个线程的函数,应该使用 p_stop
指针从另一个线程停止。
我不想知道有什么更好的方法来解决这种黑客行为背后的真正原因。我只是想知道这是否是 C++ 中已定义\未定义的行为(就此而言为 11),以及这是否依赖于编译器\平台\等。到目前为止,我看到@Puppy 说每个人都错了,这是错误的,但没有引用表示这一点的特定标准。
我知道你们中的一些人对“不要教训我”的部分感到冒犯,但请坚持真正的问题——我应该使用 volatile
吗?或者这是UB?如果可以,请提供完整的答案,帮助我(和其他人)学习新知识。
最佳答案
I simply want to know if this is defined\undefined behavior in C++ (11 for that matter)
Ta-da(来自 N3337,“准 C++11”)
Two expression evaluations conflict if one of them modifies a memory location [..] and the other one accesses or modifies the same memory location.
§1.10/4
和:
The execution of a program contains a data race if it contains two conflicting actions in different threads, at least one of which is not atomic, and neither happens before the other. Any such data race results in undefined behavior. [..]
§1.10/21
您正在从不同的线程访问对象stop
(的内存位置),这两种访问都不是原子的,因此也没有“发生在之前”的关系。简而言之,您有数据竞争,因此存在未定义的行为。
I am not interested in knowing what better ways there are to solve the real reason that is behind this sort of hack.
原子操作(由 C++ 标准定义)是(可靠地)解决此问题的唯一方法。
关于c++ - 指向堆栈变量的指针应该是易变的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43265448/
我是一名优秀的程序员,十分优秀!