指向堆栈变量的指针应该是 volatile 吗?

ZivS

我知道我应该使用volatile关键字来告诉编译器不要优化内存读写变量。我也知道在大多数情况下它应该只用于与 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)用 a替换while(true)从而改变*p_stop而什么也不做。

那么,在这种情况下是否需要将指针标记为 volatile 呢?

PS:请不要教我为什么不使用它,使用这个 hack 的真实代码是出于(复杂到解释的)原因这样做的。

编辑:

  1. 我没有提到这两个函数在不同的线程上运行。worker()是第一个线程的函数,应该使用p_stop指针从另一个线程停止

  2. 我不想知道有什么更好的方法可以解决这种 hack 背后的真正原因。我只是想知道这是否是 C++ 中的定义\未定义行为(11),以及这是否依赖于编译器\平台\等。到目前为止,我看到@Puppy 说每个人都错了,这是错的,但没有引用表示这一点的特定标准。

我知道你们中的一些人对“不要教我”部分感到冒犯,但请坚持真正的问题 - 我应该使用volatile还是不使用或者这是UB?如果可以的话,请通过提供完整的答案来帮助我(和其他人)学习新东西。

丹尼尔·戴

我只是想知道这是否是 C++ 中的定义\未定义行为(11)

Ta-da(来自N3337,“准 C++11”)

如果其中一个修改了内存位置 [..] 而另一个访问或修改了相同的内存位置,则两个表达式计算会发生冲突。

§1.10/4

和:

如果一个程序在不同的线程中包含两个相互冲突的动作,那么它的执行就包含数据竞争,其中至少一个不是原子的,并且都不在另一个之前发生。任何此类数据竞争都会导致未定义的行为。[..]

§1.10/21

您正在stop从不同的线程访问(的内存位置)对象,这两种访问都不是原子的,因此也没有“发生在之前”的关系。简而言之,您有数据竞争,因此存在未定义的行为

我不想知道有什么更好的方法可以解决这种 hack 背后的真正原因。

原子操作(由 C++ 标准定义)是(可靠地)解决这个问题唯一方法。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

std :: string类成员应该是指针吗?

来自分类Dev

这是在 Java 中使用 volatile 变量的好例子吗?

来自分类Dev

x86调用约定:堆栈传递的参数应该是只读的吗?

来自分类Dev

模板函数应该是静态的吗?

来自分类Dev

主键应该是常量int吗?

来自分类Dev

IEventStore实例应该是静态的吗?

来自分类Dev

应该是简单的XPATH吗?

来自分类Dev

js断言应该是错误的吗?

来自分类Dev

应该是简单的XPATH吗?

来自分类Dev

片段应该是独立的吗?

来自分类Dev

哨兵的数量应该是奇数吗?

来自分类Dev

访问释放的指针,输出不应该是分段错误吗?

来自分类Dev

访问释放的指针,输出不应该是分段错误吗?

来自分类Dev

VSCode表示在python中使用+ = 1进行更改的变量应该是常量。这个对吗?

来自分类Dev

指向volatile char的volatile指针。额外的静态关键字

来自分类Dev

有什么理由不应该对C中的所有变量和函数声明使用“ volatile”关键字吗?

来自分类Dev

我应该在此库中(以及在何处)使用volatile吗?

来自分类Dev

我应该在执行查询的函数中使用STABLE或VOLATILE吗?

来自分类Dev

我应该声明java.util.concurrent.ConcurrentLinkedQueue引用为volatile吗?

来自分类Dev

这应该是中间件吗?

来自分类Dev

私有最终字段也应该是静态的吗?

来自分类Dev

对于不同的类,serialVersionUID应该是唯一的吗?

来自分类Dev

RestTemplate应该是静态全局声明的吗?

来自分类Dev

CoreData:不是null属性应该是可选的吗?

来自分类Dev

字符串常量类应该是静态的吗?

来自分类Dev

聚合应该是事件处理程序吗

来自分类Dev

“ Comparable <T>”应该是“功能接口”吗?

来自分类Dev

构造函数调用的方法应该是静态的吗?

来自分类Dev

这不应该是var而不是let吗?

Related 相关文章

  1. 1

    std :: string类成员应该是指针吗?

  2. 2

    这是在 Java 中使用 volatile 变量的好例子吗?

  3. 3

    x86调用约定:堆栈传递的参数应该是只读的吗?

  4. 4

    模板函数应该是静态的吗?

  5. 5

    主键应该是常量int吗?

  6. 6

    IEventStore实例应该是静态的吗?

  7. 7

    应该是简单的XPATH吗?

  8. 8

    js断言应该是错误的吗?

  9. 9

    应该是简单的XPATH吗?

  10. 10

    片段应该是独立的吗?

  11. 11

    哨兵的数量应该是奇数吗?

  12. 12

    访问释放的指针,输出不应该是分段错误吗?

  13. 13

    访问释放的指针,输出不应该是分段错误吗?

  14. 14

    VSCode表示在python中使用+ = 1进行更改的变量应该是常量。这个对吗?

  15. 15

    指向volatile char的volatile指针。额外的静态关键字

  16. 16

    有什么理由不应该对C中的所有变量和函数声明使用“ volatile”关键字吗?

  17. 17

    我应该在此库中(以及在何处)使用volatile吗?

  18. 18

    我应该在执行查询的函数中使用STABLE或VOLATILE吗?

  19. 19

    我应该声明java.util.concurrent.ConcurrentLinkedQueue引用为volatile吗?

  20. 20

    这应该是中间件吗?

  21. 21

    私有最终字段也应该是静态的吗?

  22. 22

    对于不同的类,serialVersionUID应该是唯一的吗?

  23. 23

    RestTemplate应该是静态全局声明的吗?

  24. 24

    CoreData:不是null属性应该是可选的吗?

  25. 25

    字符串常量类应该是静态的吗?

  26. 26

    聚合应该是事件处理程序吗

  27. 27

    “ Comparable <T>”应该是“功能接口”吗?

  28. 28

    构造函数调用的方法应该是静态的吗?

  29. 29

    这不应该是var而不是let吗?

热门标签

归档