来自ISO / IEC 9899:201x第5.1.2.3节程序执行第4段:
在抽象机器中,所有表达式都按语义指定进行计算。实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用)。
这里关于volatile对象的允许优化到底是什么?有人可以提供一个可以优化的易失性访问示例吗?
由于挥发物的获取是一种可观察到的行为(如第6段所述),似乎没有优化可以取决于挥发物,因此,我很想知道第4节中允许的优化。
有人可以提供一个可以优化的易失性访问示例吗?
我认为你误解了文本,IMO本段意味着
volatile unsigned int bla = whatever();
if (bla < 0) // the code is not evaluated even if a volatile is involved
重新格式化:
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).
在我的理解中添加另一个适合此的示例:
volatile int vol_a;
....
int b = vol_a * 0; // vol_a is not evaluated
必须评估对易失性对象的访问。短语“包括任何...”修改了“副作用”。它不会修改“如果它可以推断......”它具有与以下相同的含义:
实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用)。
这意味着“副作用”包括由访问易失性对象引起的副作用。为了确定它不能评估表达式的一部分,实现必须推断出不会产生任何所需的副作用,包括由调用函数或访问易失性对象引起的任何副作用。
这并不意味着实现可以放弃对表达式的一部分的评估,即使该表达式包括对易失性对象的访问。
如果对易失性对象的访问会以使程序实现其目的所必需的方式影响系统行为,则不得省略这种访问。如果访问对系统行为没有任何影响,则可以在抽象机器上“执行”操作,而不必执行任何指令。然而,编译器编写者很难确切地知道执行指令执行访问的效果与假装在抽象机器上执行这些指令同时在真实机器上跳过这些指令的效果相同。
在更常见的情况下,编译器编写者不会对易失性访问可能产生的任何影响有特别的了解,但也没有特别的理由相信这样的访问不会产生编译器编写者不知道的影响(例如,由于涉及某些地址的操作触发的硬件,编译器编写者必须允许这样的访问可能通过以指定的顺序执行它们而具有“有趣”的效果,而不考虑编译器编写者是否知道操作顺序应该重要的任何特殊原因。