推测条件执行C / C ++

时间:2018-04-17 15:14:02

标签: c if-statement conditional

因此,我与一位同事讨论了评估执行的顺序。 考虑这个条件:

if (a > b && ref++) { do something }

我们都同意按照C标准,订单是从左到右。然而, 不同意见是,尽管有评估的顺序,但最终评估数据的一些指令可能会被推测性地执行,然后尽管进行了懒惰的评估,仍然保持这种状态。

例如,ref在评估a > b之前递增,评估仍然从左到右发生,即jump greater than和{{a > b的实际rev > 0指令1}}从左到右依次执行,并在第一个实例时放弃!true。现在这违背了懒惰评估的整个概念,但如果ref是指令流,内联函数可能会怎样。开始以推测方式执行某些指令会更有意义。关注的是:这些指示是否已经发生,甚至是中途。

思想?

3 个答案:

答案 0 :(得分:8)

运营商&&(以及运营商||)在某种意义上是特殊的,因为它们保证了从左到右的“快捷评估”。这意味着,对于像expr1 && expr2这样的条件,expr1将始终首先进行评估,并且 - 甚至更多 - 如果expr2已经评估为expr1,则if (a > b && ref++)将无法进行评估假。这不是优化,这是由语言保证的。

因此,在ref++中,当且仅当ref评估为a > b时,才会评估表达式true(包括递增ssh user1@gateway的副作用) 。

答案 1 :(得分:1)

由于a > b && ref++运营商短路&&无法实现。

想想那个案子:

f = fopen("foo.txt");
if ((f != NULL) && fread(buffer,10,1,f)) { ...

如果f==NULL错误,则执行第二部分,因为第一部分可以防止它。

相反,没有什么能阻止编译器在这里做任何想做的事情:

a > b & ref++

&是算术,因此始终执行这两个条件。因此,即使第一个条件为假,ref也会递增。

答案 2 :(得分:1)

允许C编译器实现“as-if”规则,这意味着只要程序的 intent 得到尊重,他们就可以做任何他们喜欢的事情。

考虑(a > b && ref++)。这里的意图是,如果refa > b,则1 这是因为只有当左手参数为&&时,才会评估1的右手参数。但是,生成的汇编代码可能会使CPU可以推测性地增加ref分支预测),并在适当的情况下使用管道转储撤消该增量。