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

use*_*019 5 c++ language-lawyer

允许多次访问吗?

#include <iostream>

int main()
{
    int A[1];
    A[0] = 0;
    A[A[0]] = 1;
    std::cout << A[0];
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Lig*_*ica 8

是的,它是有效的.

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

int x = 42;
x = x + 1;
Run Code Online (Sandbox Code Playgroud)

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

其次,单独评估A[A[0]]是非常好的:

[C++11: 1.9/15]: [..]运算符的操作数的值计算在运算符的结果的值计算之前被排序.[..]

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

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