考虑以下(有些荒谬)if语句:
int i = 0;
int j = 0;
//get i, j from the user, or a file, or something
if(i < 6 && j > 4)
...
else if(j > 6)
...
现在,这会编译成如下所示:
else if
,如果不是else if
,如果不是else if
:比较j&gt; 6(即使上面的第二个比较是假的,这可能不是真的)还是有一些预测简化逻辑的智能方法吗?
答案 0 :(得分:2)
关于precedence。
你的第一个表达式是这样处理的(大括号使它明确易读):
(i < 6) && (j > 4)
但是,如果不知道操作发生的顺序,就不知道了。
示例,以下哪一项是等效的:
&x[5]
&(x[5])
(&x)[5]
正如您所指出的,C语言使用Short-Circuit Evaluation。 这意味着一旦它知道语句的结果,它就会停止处理。
x = 3;
if ((x < 6) || do_foo()) {
/* ... */
}
if ((x < 10) && do_bar()) {
/* ... */
}
在这种情况下,do_foo()
函数未被调用,但调用了do_bar()
函数。
出于这个原因,从一个明确的意图,以及一个有目的的编程观点(你可能是一个优先专家,在一个条件中)放置任何“可能做某事”的陈述是一个坏主意。但下一个人可能不是。)
答案 1 :(得分:0)
如果编译器可以证明if
的条件始终具有某个值,则可能会禁止从生成的代码进行检查。如果您在启用优化的情况下进行编译,通常会执行此操作,编译器将尝试在语义上分析代码并证明这类事情。
使用if(0) { /* ... */ }
是用于删除部分代码的常用习惯用法,我知道优化编译器不会为其发出任何代码。
也就是说,我不知道是否有任何编译器会执行您提到的这种特定优化:在j&gt;情况下完全跳过else if
4,但我不会对GCC或Clang感到惊讶,因为他们执行相当激进的代码转换。