'a [i] = i;'总是导致行为明确吗? [英] Does 'a[i] = i;' always result in well defined behaviour?

查看:33
本文介绍了'a [i] = i;'总是导致行为明确吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此处提出了一些有关C语言中未定义行为的有趣问题.其中一个是(略有修改)

There are several interesting questions raised here regarding undefined behaviour in C. One of them is (slightly modified)

下面的代码是否会导致不确定的行为?

Does the following piece of code result in undefined behaviour?

int i = 0, *a = &i;   // Line 1
a[i] = i + 1;         // Line 2

由于那里的这部分问题没有具体答案,而且我有兴趣了解C ++中的行为,因此在这里再次提出.

Since there is no concrete answer to this part of the question there, and I am interested in knowing the behaviour in C++, I am raising it again here.

未定义行为和顺序点的规则#2

此外,应仅访问先前值以确定要存储的值

Furthermore, the prior value shall be accessed only to determine the value to be stored

很明显,在上面的示例中,该值被访问了两次: a [i] (lhs)和 i (rhs),只有一个(rhs)确定要存储的值.

Clearly in the example above, the value is being accessed twice: a[i] (lhs) and i (rhs), and only one of them (the rhs) determines the value to be stored.

第2行是否违反了上述规则,并导致C ++ 03中出现未定义的行为?

关于是否在第2行修改了 i 还是有些困惑?

There is some confusion as to whether i is modified at Line 2?

> 是的,它已被修改!

推荐答案

这将导致C ++ 03中的行为不确定,而C ++ 11中的行为明确.

This will result in undefined behavior in C++03, and well-defined behavior in C++11.

C ++ 03:未定义行为

根据C ++ 03标准,第5节第4段:

From the C++03 standard, section 5 paragraph 4:

在上一个序列点和下一个序列点之间,标量对象应通过表达式的计算最多对其存储值进行一次修改.此外,仅可访问先前值来确定要存储的值.

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.

请注意第二句话: i 的先前值只能用于确定要存储的值.但是这里它也用于确定数组索引.因此,因为此分配将修改 i ,所以 a [0] = i + 1 的定义很明确,而 a [i] = i + 1 不是.请注意,赋值不会生成序列点:只有完整表达式(分号)的结尾会生成.

Note the second sentence: The previous value of i can only be used to determine the value to be stored. But here it is also used to determine the array index. So because this assignment will modify i, a[0] = i+1 is well defined, while a[i] = i+1 is not. Note that the assignment does not generate a sequence point: only the end of the full expression (the semicolon) does.

C ++ 11:行为明确:

C ++ 11摆脱了序列点的概念,而是定义了哪些求值先于哪个求值.

C++11 got rid of the notion of sequence points, and instead defines which evaluations are sequenced before which.

根据标准,第1.9节第15段:

From the standard, section 1.9 paragraph 15:

运算符的操作数的值计算在运算符结果的值计算之前进行排序.如果相对于同一标量对象的另一副作用或使用同一标量对象的值进行的值计算,未对标量对象的副作用进行排序,则该行为是不确定的.

The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

赋值运算符的两个操作数都在实际赋值之前进行排序.因此,将同时评估 a [i] i + 1 ,然后才对 i 进行修改.结果定义明确.

Both operands of the assignment operator are sequenced before the actual assignment. So both a[i] and i+1 will be evaluated, and only then will i be modified. The result is well defined.

这篇关于'a [i] = i;'总是导致行为明确吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆