【问题标题】:Are volatile data members trivially copyable?易失性数据成员是否可以轻松复制?
【发布时间】:2012-11-15 22:57:42
【问题描述】:

在写this answer 时,我意识到我对自己的结论并不像我通常在点击发布您的答案之前所确保的那样自信。

对于volatile 数据成员的琐碎可复制性是实现定义的或完全不允许的论点,我可以找到一些相当有说服力的引文:

但我无法在标准1 本身中对此进行备份。特别“令人担忧”的是,在实际标准的最终措辞中,没有迹象表明提议的措辞与 n3159 问题列表相比有所改变。

那么,什么给了? volatile 数据成员是否可以轻松复制?


1  C++11

【问题讨论】:

  • 我刚刚发现 issue #496 中提议的措辞更改只有一个月左右的时间,因此,晚于 C++11。因此它仍然处于活动状态。我想那我问的只是与 Maddock 2004 年以 #496 开始时一样的问题。

标签: c++ c++11 volatile language-lawyer


【解决方案1】:

我看到以下“可简单复制”的定义(C++11 §3.9,第 9 段):

...标量类型、可平凡复制的类类型、此类类型的数组、和这些类型的cv-qualified版本统称为可平凡复制 类型....

cv-qualified 根据定义包括const 和/或 volatile (§3.9.3)。因此,如果非限定类型是可平凡复制的(标量或可平凡复制的类类型,或其数组),volatile 值似乎是显式可平凡复制的。

【讨论】:

  • 但是请看 issue #496,它表明这个措辞不准确,并且可能与其他地方的措辞不一致。您引用的段落在那里被明确挑出来。
  • @LightnessRacesinOrbit: C++ 中的volatile 与 Java 中的不同。我还没有看到它在 C++ 中暗示原子性的地方,因此假设它没有。这是我能想到的唯一与标准其余部分一致的解释。
  • 除非委员会成员明显不同意,因此无法得出结论。因此我的问题:(问题是,虽然标准不能保证volatile 对象的原子性,但可以说volatile 对象的 any 属性足以暗示实现定义性对他们中的大多数人来说。我认为这就是 Maddock 的来源。我实际上在这一点上对 DR 有一半的期待。
  • Maddock 关于原子性的基本原理,引用自活跃问题:The problem with this is that a volatile qualified type may need to be copied in a specific way (by copying using only atomic operations on multithreaded platforms, for example) in order to avoid the “memory tearing” that may occur with a byte-by-byte copy. 当然,目前,该标准并未涉及此类事情——但某些实现可能需要(参见:GCC 4.7,来自原始问题),因此,3.9/9 似乎是一个缺陷,因此实际上不具有约束力。因此#496。
  • 为了避免“内存撕裂”而必须做的事情......如果它想提供这样的保证,那就是实现的问题。 C++ 不需要它。 (它是否会在未来的某个版本中不会改变今天的标准。)基本上所有volatile 意味着无论如何你要禁止缓存旧的优化价值观。如果您依赖的不仅仅是这些,您就必须询问编译器制造商什么是安全的,什么不是,并且知道您正在使用特定于实现的行为。
【解决方案2】:

缺陷报告CWG496CWG2094 更改了答案。后者 DR 还原前者。

现在,对于 volatile 非静态数据成员,

  • 如果成员是标量类型或可能是多维数组,则不会使类不可复制,但是
  • 如果 的成员是类类型或可能是其中的多维数组,则包含类的隐式声明的复制/移动函数都将被删除,这使得类不可复制(自CWG1734)。

【讨论】:

    猜你喜欢
    • 2011-01-03
    • 2011-03-10
    • 2018-08-09
    • 2011-06-17
    • 2016-03-24
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多