繁体   English   中英

C ++是否按规则允许商店重新排序?

[英]Is store reordering allowed by C++ as-if rule?

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

至于“可观察到的行为”到底代表什么, cppreference.com似乎与标准给出的输入/输出定义不同。 我不确定这是对标准的重新解释还是错误。

cppreference.com的“ 假设 ”规则:

  • 所有输入和输出操作都以相同的顺序发生,并且具有相同的内容,就好像程序是按编写的方式执行的一样。

该标准的“ 如果 ”规则:

  • 交互式设备的输入和输出动态应该以一种方式进行,即在程序等待输入之前,实际上会发出提示输出。 交互设备的构成由实现定义

这种差异对我很重要,因为我想知道常规的存储重新排序是否是有效的编译器优化。 按照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 生成以下代码

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

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

如果cppreference.com与C ++标准的实际文本不一致,则cppreference.com错误。 唯一可以取代标准文本的是标准的更新版本,以及缺陷报告的官方解决方案 (有时会汇总到名为“ technical corrigienda”的文档中,该名称是次要版本的花哨名称)。标准)。

但是,在这种情况下,您误解了cppreference.com通过“输入和输出操作”的含义。 (如果有内存,则该文本将逐字取自该标准的较早版本。)存储到内存中不是输出操作。 对于此规则,仅写入文件 (即任何stdio.hiostream输出流,或其他实现定义的机制,例如Unix文件描述符)才算作输出。

在2011年修订版之前,C和C ++标准假定使用单线程抽象机,因此无需费心指定任何有关商店订购的信息,因为没有办法观察程序顺序之外的商店。 C(++)11为新的多线程规范的一部分添加了一大堆商店订购规则。

在标准的第1.9 / 8节中找到了假设规则的真实表达:

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

由于AB都不易失,因此可以重新排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM