为什么 volatile 在 C++20 中被弃用?

康桓瑋*_*康桓瑋 33 c++ volatile c++20

根据cppreferencevolatile关键字的大多数用法在 C++20 中将被弃用。的缺点是volatile什么?不使用时的替代解决方案是什么volatile

unD*_*rbs 21

C++ 委员会语言演变主席对原因进行了很好的讨论。

简而言之,许多volatile被移除的地方没有任何可以理解的意义,只是造成了混乱。


演讲中的一些例子:

  • 易失性位域应由您的硬件手册和/或编译器指定。
  • +=单个/原子指令吗?怎么样++
  • 需要多少次读/写compare_exchange?如果失败了怎么办?
  • 什么void foo(int volatile n)意思?或者int volatile foo()
  • 应该*vp;做负载吗?(这在标准中已经改变了两次。)

  • 我想最后的问题是: std::atomic<> 是否检测到它何时没有在多线程环境中编译,在这种情况下,只需使用简单的递减和递增而不是原子操作,这可能会明显降低性能。 (3认同)
  • @DavidBien:您可以使用 x86 的 `gcc -Wa,-momit-lock-prefix=yes` 来编译使用 `std::atomic` 的单线程代码。这只是让汇编器通过传递“-momit-lock-prefix=yes”选项来忽略“lock”前缀;它不会让编译器将内容优化到寄存器中,但是“add [mem], 1”只是一个正常的内存目标增量,而不是原子 RMW(也不是内存屏障)。这意味着您不必滥用“易失性”作为“原子<T>”的单线程版本,我认为这就是您在现代 C++ 中针对易失性提出多线程的原因。 (3认同)
  • 我似乎无法弄清楚他们是否正在弃用易失性限定方法。按照 https://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766 的方式编写“易失性正确代码”是一个很好的模型。我希望他们的目的不是要打破这个模式。 (2认同)
  • 目的是强制使用 std::atomic< int > ,然后它将正确支持预减和预增量 - 即通过正确使用原子指令。然而,当为多线程和非多线程使用编写通用代码时,会导致 const_cast<> 变通办法,其中模板实现者必须将 volatile int (在非多线程编译中)强制转换为 int 以避免弃用警告。因此,很烦人并导致额外的工作。\ (2认同)
  • 我还假设 `std::atomic` 不会检查是否启用了线程;然而,这并不是滥用“易失性”线程的理由。“易失性”旨在描述硬件何时可以与您的程序交互,并且仅具有禁用优化器的效果,这不是它想要的含义。如果在单线程环境中优化“原子”是一个严重的问题,我会向您的编译器实现者询问该功能。但是,我还想知道为什么在单线程代码中使用同步功能。 (2认同)