1

我见过一种特殊风格的代码,在我看来它是危险的,应该避免,但我在很多地方都看到过很多次,我很困惑我是否遗漏了什么。

int a[100];

/* Some code later */

for(i =0; (i < 100 && a[i] != 0); i++)
           :
           :

在上面的代码中,表达式 (i < 100 && a[i] != 0) 可能是从右到左计算的,在这种情况下,当 i == 100 时,我们将超出数组 'a 的范围'。

有人可以解释这是否是安全代码

4

5 回答 5

4
  1. 评估或参数的顺序已明确定义&&,不能更改。
  2. #1加上短路使这非常安全。

参考:

C++03 标准:

第 5 节:表达式,第 4 段:

除非另有说明[例如&& 和 || 的特殊规则 ],单个运算符的操作数和单个表达式的子表达式的计算顺序以及副作用发生的顺序是未指定的。

C99 标准:

第 6.5 节:

运算符和操作数的分组由语法表示。72) 除稍后指定(对于函数调用 ()、&&、||、?: 和逗号运算符)外,子表达式的求值顺序和中的顺序发生哪些副作用都未指定。

注意:强调我的。

于 2013-06-19T04:48:38.233 回答
3

我认为您可以指望短路评估a[i]在错误时不访问i < 100

于 2013-06-19T04:46:56.363 回答
2

(i < 100 && a[i] != 0)从右到左评估是不可能的。&&并且||被明确定义为首先评估其左参数,仅在必要时才评估其右参数。

于 2013-06-19T04:47:05.450 回答
1

“在上面的代码中,表达式 (i < 100 && a[i] != 0) 可能是从右到左计算的......”

不,这是不可能的,无论是在 C 中还是在 C++ 中。在这两种语言中,保证从左到右计算这个表达式。如果第一部分为假,则保证第二部分不被评估。

因此,代码完全不受越界访问的影响。

于 2013-06-19T04:55:53.810 回答
0

&& 和 || 正如每个人所说,从左到右进行评估。您可能需要考虑以下链接以获取更多信息

http://en.cppreference.com/w/cpp/language/operator_precedence

于 2013-06-19T04:54:58.290 回答