为了账号安全,请及时绑定邮箱和手机立即绑定

“以假乱真”的规则到底是什么?

“以假乱真”的规则到底是什么?

C++ C
智慧大石 2019-06-10 16:40:44
“以假乱真”的规则到底是什么?正如标题所说,“以假乱真”的规则到底是什么?一个典型的答案是:允许不改变程序可观察行为的任何和所有代码转换的规则。我们不时地从特定的实现中获取行为,这些行为都归因于这个规则。很多次都是错误的。那么这条规则到底是什么。标准没有明确提到这条规则作为一节或一段,那么究竟什么属于这一规则的范围?在我看来,这似乎是一个灰色地带,标准没有详细界定。有人能详细说明引用标准参考的细节吗?注意:将其标记为C和C+,因为它与这两种语言都相关。
查看完整描述

3 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

什么是“如-“规则?

如-规则基本上定义了在合法的C+程序上允许实现执行的转换。简而言之,所有不影响程序的转换可观察行为“(确切定义见下文)。

目标是让实现可以自由地执行优化,只要程序的行为与C+标准在抽象机器方面指定的语义保持一致。


标准在哪里引入这项规则?

C+11标准引入了如-“第1.9/1段中的规则:

这个国际标准中的语义描述定义了一个参数化的非确定性抽象机器。本国际标准不对一致性实现的结构提出任何要求。特别是,它们不需要复制或模仿抽象机器的结构。相反,一致性实现需要(仅)模拟(仅)可观察行为关于抽象机器的说明如下所示。

此外,一个解释性脚注还补充说:

这一规定有时被称为“以假乱真”规则。,因为一个实现可以自由地无视本国际标准的任何要求,只要结果是好像该要求已经被遵守一样,就可以从程序的可观察到的行为来确定。例如,一个实际的实现不需要评估一个表达式的一部分,如果它可以推断它的值没有被使用,并且没有产生影响程序的可观察行为的副作用。


规则究竟规定了什么?

第1.9/5段进一步具体规定:

符合要求的实施执行格式良好的程序将产生与具有相同程序和相同输入的抽象机器相应实例的可能执行之一相同的可观察行为。..但是,如果任何此类执行包含未定义的操作,则本国际标准不要求使用该输入执行该程序(甚至不要求执行第一个未定义操作之前的操作)。

值得强调的是,这种约束适用于“执行格式良好的程序”只有,并且执行包含未定义行为的程序的可能结果是不受约束的。第1.9/4段也明确说明了这一点:

在本国际标准中,某些其他操作被描述为未定义的操作(例如,试图修改Const对象的效果)。[注:本国际标准不对包含未定义行为的程序的行为施加任何要求..-尾注]

最后,关于“的定义”可观察行为“,第1.9/8号决议如下:

对符合标准的实现的最低要求是:

-对易失性对象的访问严格按照抽象机器的规则进行评估。

-在程序结束时,所有写入文件的数据应与按照抽象语义执行程序可能产生的结果相同。

-交互设备的输入和输出动态应在程序等待输入之前实际交付。构成交互设备的是实现定义的。

这些统称为程序的可观察行为。. [ :每个实现都可以定义抽象语义和实际语义之间更严格的对应关系。-尾注 ]


是否有此规则不适用的情况?

据我所知,唯一的例外是如-“规则是复制/移动省略,即使类的复制构造函数、移动构造函数或析构函数有副作用,也允许这样做。

如果满足某些条件,则允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用. [...]


查看完整回答
反对 回复 2019-06-10
?
阿晨1998

TA贡献2037条经验 获得超6个赞

在C11中,该规则从未被称为该名称。然而,与C+一样,C也用抽象机器来定义行为。如果规则在c11 5.1.2.3p4和p6:

  1. 在抽象机器中,所有表达式都由语义指定。实际的实现不需要评估表达式的一部分,如果它可以推断它的值没有被使用,并且没有产生任何所需的副作用(包括调用函数或访问易失性对象所引起的任何副作用)。

  2. [...]

  3. 对符合标准的实现的最低要求是:

     

    这是程序的可观察的行为。

    • 访问

      volatile

      对象严格按照抽象机器的规则进行评估。
    • 在程序结束时,所有写入文件的数据应与按照抽象语义执行程序所产生的结果相同。
    • 交互设备的输入和输出动态应按

      7.21.3

      ..这些要求的目的是使未缓冲或行缓冲的输出尽快出现,以确保提示消息在等待输入的程序之前实际出现。


查看完整回答
反对 回复 2019-06-10
  • 3 回答
  • 0 关注
  • 510 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信