数组指针算法 – 合法和未定义的行为

我问自己这些代码行是否会在C和C ++中产生未定义的行为。 我试着回答每一点,阅读标准关于数组下标的内容(C 6.5.6 – 8)。 我没有发布整个段落,因为它很长。

此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向一个超过数组对象的最后一个元素,如果表达式Q指向一个超过数组对象的最后一个元素,表达式(Q)-1指向数组对象的最后一个元素。 如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义。 如果结果指向一个超过array> object的最后一个元素的结果,则它不应该用作被计算的一元*运算符的操作数。

  1 int a[10]; 2 int b = a[9]; // ok 3 int c = a[10]; // UB 4 int* d = (a + 10); // ok 5 int* e = &a[10]; // ok from C99 (& and [] are ignored, pointer is not deferenced), // UB in pre C99 6 int* f = &a[11]; // ok from C99, UB in pre c99 int* g = a; 7 int* h = g + 15; // ok 

我认为相同的aswers应该对C ++有效

这些行在C和C ++中是否有效,我误解了标准吗?

6和7都不是有效的,因为它们不在现有数组内执行指针运算(包括一个过去的指针)。 其他一切基本上都是正确的。

仅在C中:假设a[i]*(a + i) ,并且&*p总是只是p而没有评估*p ,5应该总是很好,尽管你是对的,C89没有指定这个这只是在C99中添加的。 (在C ++中根本不是这样,运算符可能会过载而且没有提到组合&* 。)

从n1570(草案到C11),6.5.6添加剂操作员的第8段:

[…]如果指针操作数和[ P + N ]的结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不会产生溢出; 否则,行为未定义。 […]

C ++包含非常相似的措辞(例如C ++ 11,5.7 / 5)。