这是对序列点之间同一对象的多次访问定义良好的行为吗?

时间:2015-03-23 16:30:39

标签: c++ language-lawyer

是否允许多次访问?

#include <iostream>

int main()
{
    int A[1];
    A[0] = 0;
    A[A[0]] = 1;
    std::cout << A[0];
}

请参阅以下段落......

  

除非另有说明,否则评估个人操作数的顺序   个体表达式的运算符和子表达式,以及   发生副作用的顺序是未指定的。在前一个和下一个序列点之间,标量对象应该是   通过评估a,最多修改一次存储值   表达。此外,只能访问先前值   确定要存储的值。本段的要求   对于a的子表达式的每个允许排序,应满足   充分表达;否则行为未定义。

如果这使用A [0]的旧值,它应该是未定义的行为,对吗?

1 个答案:

答案 0 :(得分:8)

是的,它有效。

首先,在赋值的LHS上阅读A[0]是完全有效且定义明确的原因与此相同:

int x = 42;
x = x + 1;

必须先评估两个操作数,然后才能执行赋值。

其次,单独评估A[A[0]]是可以接受的:

  

[C++11: 1.9/15]: [..] 一个操作数的值计算   在运算符结果的值计算之前对运算符进行排序。 [..]

在C ++ 03中,我能找到的最接近的相关措辞是关于赋值的以下内容(尽管有一些结构如a = a + x遍布gaff):

  

[C++03: 5.17/8]:如果存储在对象中的值是从另一个以第一个对象的存储方式重叠的对象访问的,则重叠应该是精确的,并且两个对象应具有相同的类型,否则行为未定义。