允许在易失对象上进行优化

共5个回答,已解决, 标签: c optimization language-lawyer volatile

Iso/iec 9899:201x部分5.1.2.3 计划执行第 4 段:

在抽象计算机中, 所有表达式都按语义指定进行计算。实际实现不需要计算表达式的一部分, 如果它可以推断它的值没有使用, 并且不产生所需的副作用(包括因调用函数或访问可变对象**而导致的任何结果**)。

对于波动对象, 这里允许的优化究竟是什么?有人能给出一个可以优化的易失性访问的例子吗?

由于挥发物的获取是一种可观察到的行为 (第 6段描述), 似乎任何优化都不能对挥发性物质感到满意, 所以, 我很想知道第 4节允许进行哪些优化。

第1个答案(采用)

有人能给出一个可以优化的易失性访问的例子吗?

我认为你误解了案文, 海事组织本段的意思是:

volatile unsigned int bla = whatever();

< 0)="" the="" code="" is="" not="" evaluated="" even="" if="" a="" volatile="" is="" involved="">
第2个答案

重新格式化一点:

An actual implementation need not evaluate part of an expression if:

  a) it can deduce that its value is not used; and

  b) it can deduce that that no needed side effects are produced (including any
     caused by calling a function or accessing a volatile object).

在不更改含义的情况下反转逻辑:

An actual implementation must evaluate part of an expression if:

  a) it can't deduce that its value is not used; or

  b) it can't deduce that that no needed side effects are produced (including
      any caused by calling a function or accessing a volatile object).

简化以专注于易挥发部分:

An actual implementation must evaluate part of an expression if needed
side effects are produced (including accessing a volatile object).
第3个答案

添加另一个符合我理解的示例:

volatile int vol_a;
....
int b = vol_a * 0; // vol_a is not evaluated
第4个答案

必须评估对易失对象的访问。"包括任何......" 一语修改 "副作用"。它不会修改 "如果它可以推断..."它的含义与以下相同:

实际实现不需要计算表达式的一部分, 如果它可以推断它的值没有使用, 并且不会产生所需的副作用 (包括由调用函数或访问可变对象引起的任何副作用)。

这意味着 "副作用" 包括访问易失对象所引起的副作用。为了确定它不能计算表达式的一部分, 实现必须推断不会产生任何所需的副作用, 包括由调用函数或访问可变对象引起的任何副作用。

这并不意味着实现可以放弃对表达式的一部分的计算, 即使该表达式包含对可变对象的访问。

第5个答案

如果对可变对象的访问将以使程序实现其目的所必需的方式影响系统行为, 则不能省略这种访问。 如果访问对系统行为没有任何影响, 则可以在抽象计算机上 "执行" 操作, 而无需执行任何指令。 但是, 编译器编写器很少能肯定地知道执行指令执行访问的效果与在虚拟计算机上跳过这些指令时假装执行这些指令的效果相同。

在更常见的情况下, 编译器编写器不会特别了解可变访问可能产生的任何影响, 但也没有特别的理由相信这种访问不会产生编译器编写器所没有的效果了解 (例如, 由于涉及某些地址的操作触发的硬件), 编译器编写器必须允许这样的访问可能会产生 "有趣" 的影响, 通过按指定的顺序执行它们, 而不考虑编译器编写器是否知道操作序列应该重要的任何特定原因。

相关问题

我投的是 malloc 的结果吗? 为什么是统计:: st _ size 0 为设备, 但同时 lseek 正确地定义了设备大小? 允许在易失对象上进行优化 优化乘加 尽可能快地比较表单中的两个值 (a sqrt (b))? 如何将模板参数从类型更改为非类型, 使 SFINAE 工作? 访问 std:: 字符串中的元素, 其中字符串的位置大于其大小 铸铁挥发阵列阵列的非易失性 编译器允许不断折叠本地易失性吗?