C ++ as-if规则是否允许存储重新排序?

时间:2014-08-14 00:10:45

标签: c++ c++11 as-if

as-if ”规则基本上定义了允许在合法C ++程序上执行的实现的转换。简而言之,允许所有不影响程序的 可观察行为 的转换。

至于 “可观察行为” 的确切含义,cppreference.com似乎与标准提供的定义不同,关于输入/输出。我不确定这是对标准的重新解释,还是错误。

cppreference.com

as-if ”规则:

  
      
  • 所有输入和输出操作都以相同的顺序发生   相同的内容就像程序按照书面执行一样。
  •   
标准的

as-if ”规则:

  
      
  • 应进行交互设备的输入和输出动态   以这种方式提示输出实际上是在a之前传递的   程序等待输入。构成交互设备的是什么   实现定义
  •   

这种差异对我很重要,因为我想知道正常的商店重新排序是否是有效的编译器优化。根据cppreference的措辞,内存存储应该属于它提到的output operations。但根据标准,内存存储似乎不是the output dynamics of interactive devices。 (无论如何,什么是交互式设备?)

要遵循的一个例子。

int A = 0;
int B = 0;

void foo()
{
    A = B + 1;              // (1)
    B = 1;                  // (2)
}

功能foo的现代编译器may generate the following code

mov     0x804a018, %eax
movl    $0x1, 0x804a018    ; store 1 to B
add     $0x1, %eax         
mov     %eax, 0x804a01c    ; store 1 to A
ret

如图所示,A的商店与商店重新排序为B。它是否符合“ as-if ”规则?标准是否允许这种重新排序?

2 个答案:

答案 0 :(得分:3)

如果cppreference.com不同意C ++标准的实际文本,则cppreference.com是错误的。唯一可以取代标准文本的是标准的更新版本,official resolutions of defect reports(有时会被卷入称为“技术corrigienda”的文档中,这是一个很小的版本标准)。

但是,在这种情况下,您误解了“输入和输出操作”对cppreference.com的意义。 (如果内存服务,该文本将从标准的旧版本逐字逐句获取。)内存存储为 NOT 输出操作。只写入文件(即任何stdio.hiostream输出流,或其他实现定义的机制,例如Unix文件描述符)计为输出这个规则。

C和C ++标准在2011年版本之前,假定是一个单线程抽象机器,因此没有任何关于商店订购的说明,因为没有办法观察商店程序顺序。作为新的多线程规范的一部分,C(++)11为商店排序添加了一大堆规则。

答案 1 :(得分:2)

as-if规则的真实表述见标准中的§1.9/ 8:

  
      
  • 严格按照抽象机的规则评估对volatile对象的访问。
  •   
  • 在程序终止时,写入文件的所有数据应与其中一个可能的结果相同   根据抽象语义执行程序会产生。
  •   
  • 交互设备的输入和输出动态应以提示的方式进行   输出实际在程序等待输入之前传送。什么构成了交互设备   是实现定义的。
  •   

由于AB不易变,因此允许重新排序。