数组指针算法 – 合法和未定义的行为
我问自己这些代码行是否会在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)。