短路评估是否保证评估顺序?

时间:2013-10-10 18:24:38

标签: c arrays lazy-evaluation

&&的左侧部分是否始终在右侧部分之前进行评估?

我想知道,因为我想知道我是否可以改变

if(i > 0)
    if(someFunc(arr[i-1], arr[i]))
        //do work

if(i > 0 && someFunc(arr[i-1], arr[i]))

如果首先评估右侧并引用arr[0-1],这会导致未定义的行为吗?

2 个答案:

答案 0 :(得分:3)

是的,由于逻辑&&运算符的short-circuit行为,如果&&第二个表达式仅在first为true时进行求值。阅读以下内容:

  

6.5.13逻辑AND运算符

     

4与按位二进制&运算符不同,&&运算符保证left-to-right评估;   在评估第一个操作数后有一个序列点。如果是第一个操作数   比较等于0,第二个操作数评估。

来自Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

因此,如果i > 0为false(例如,如果i = 0),那么i > 0表达式的结果将为false,然后将不会调用第二个操作数someFunc(arr[i-1], arr[i](已评估)。

因此,if(i > 0 && someFunc(arr[i-1], arr[i]))代码是安全的,但要小心i - 1不应该是>最大索引值arr[]。真的,我会更喜欢这种形式,如果比较嵌套的if块(扁平比嵌套更好)。

来自@ Maroun Maroun的回答"Is there any reason for asking if(1 || Foo())?"可能对您有所帮助的其他信息:

  
      
  • if(a && b) - 如果afalse,则b不会被检查。
  •   
  • if(a && b) - 如果atrue,则会检查b,因为如果它是false,则表达式为{{} 1}}。
  •   
  • false - 如果if(a || b)a,则true不会被检查,因为无论如何这都是b
  •   
  • true - 如果if(a || b)a,则会检查false,因为如果bb,那么它就会被truetrue
  •   

答案 1 :(得分:1)

是。从左到右保证运营商&&||,? :(三元运营商)的评估顺序。在这些操作数的左右子表达式之间出现sequence point。这些运算符(&&||,)的左子表达式的所有副作用都在访问其右子表达式之前完成。

  如果首先评估右侧并引用arr[0-1]

是否会导致未定义的行为?

是。如果是这种情况,则会导致未定义的行为。 (但它不会发生这种情况,因此不存在任何未定义的行为。)