不是应该以C++规范文档作为最后的依据吗?不过也挺无聊的啊,因为实际还要看编译器的实现。
在C++ 11的规范pdf中搜"*((E1)+(E2))",可以搜到两处讲下标操作符[]的,
一处是:5.2.1 Subscripting
另一处是:8.3.4 Arrays
8.3.4节中说:
“If the value of the constant expression is N, the array has N elements numbered 0 to N-1”;
“Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such
a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an
array and E2 an integer, then E1[E2] refers to the E2-th member of E1.”
综合上面两段话,得到:
1、E1[E2]表示数组E1的第E2个元素,而数组的元素编号是从0到N-1的,所以E2严格来说只能是非负的。
2、E1[E2] 和 *((E1)+(E2)) 是等价的。
在“5.7 Additive operators”这一节的第5小段中,对某个指针加上、减去一个整数的操作进行了说明。
并且最后一句特意提到:
如果“指针本身超出了数组元素范围,并且超出了数组最后那个元素+1的范围”,
或者“加/减操作的结果超出了数组元素范围,并且超出了数组最后那个元素+1的范围”,
那么就是UB。如下:
“Moreover, if the expression P points to the last element of an array object,
the expression (P)+1 points one past the last element of the array object, and if the expression Q points
one past the last element of an array object, the expression (Q)-1 points to the last element of the array
object. If both the pointer operand and the result point to elements of the same array object, or one past
the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is
undefined.”
把one past the last element of the array object也视为有效的范围,应该是为STL中iterator的++、--、end()等服务的。
所以按规范的话,a[-1]是UB,但实际执行的结果要看编译器怎么实现的。
--
修改:z16166 FROM 123.115.163.*
FROM 123.115.163.*