数组指针运算 - 法律和未定义行为 [英] Array-pointer arithmetic - legal and undefined behaviour
问题描述
我问自己,如果这些线code的可以在C和用C产生不确定的行为++。
我试着回答每一个点读什么标准说有关数组下标(C 6.5.6 - 8)。我没有贴全款,因为它是pretty长。
此外,如果前pression
P
指向最后一个
数组对象的元素,前pression(P)+1
点中的一个过去的最后一个元素
数组对象,如果前pression问:
点中的一个过去的数组对象的最后一个元素,
恩pression(Q)-1
指向数组对象的最后一个元素。如果这两个指针
操作数和结果指向相同的数组对象的元素,或者一个过去的最后
数组对象的元素,该评估也不得产生溢出;否则,
行为是不确定的。如果结果点中的一个过去的阵列>对象的最后元件,它
不得用作评估一元*
运算符的操作数。
块引用>1 int类型的[10];
2 INT B = A [9]; // 好
3 INT C = A [10]; // UB
4 INT * D =(A + 10); // 好
5 INT * E =&放大器;一个[10]; // OK从C99(安培;和[]被忽略,指针不deferenced),//在UB pre C99
6为int * F =&放大器;一个[11]; //从C99,UB确定在pre C99
INT * G =一;
7 INT * H = G + 15; // 好我认为同样的aswers应该是有效的C ++
难道这些行有效的C和C ++中,有我误解了标准?
解决方案无论是6还是7是有效的,因为他们没有一个现有的阵列(包括一个过去的非结束指针)内执行指针运算。一切是基本上是正确的。
在仅C:鉴于
A [I]
与*(A + I)
,和&放大器; * p
永远只是p
没有评估* p
5应始终很好,虽然你说得对,C89没有规定这一点,这是只有在C99增加。 (这是不正确的在C ++中,在运算符可以重载都并没有结合提&安培;
和*
)从n1570(草案C11),在6.5.6加法运算符的第8段:
[...]如果指针操作数和结果都[的
点+ N
]指向同一个数组对象的元素,或者一个过去的最后一个元素数组的对象,该评估也不得产生溢出;否则,其行为是不确定的。 [...]
块引用>C ++包含非常类似的措辞(例如C ++ 11,5.7 / 5)。
I was asking myself if these line of code could produce undefined behaviour in C and in C++. I tried to answer to each point reading what the standard says about array subscripting (C 6.5.6 - 8). I didn't posted the entire paragraph because it is pretty long.
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 expressionQ
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. If the result points one past the last element of the array >object, it shall not be used as the operand of a unary*
operator that is evaluated.
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
I think that the same aswers should be valid for C++
Are these lines valid in C and in C++, have I misunderstood the standard?
解决方案Neither 6 nor 7 are valid, because they do not perform pointer arithmetic inside an existing array (including the one-past-the-end pointer). Everything else is essentially correct.
In C only: Given that
a[i]
is identical to*(a + i)
, and&*p
is always justp
without evaluating*p
, 5 should always be fine, although you're right that C89 does not specify this and this was only added in C99. (This is not true at all in C++, where operators can be overloaded and there is no mention of combining&
and*
.)From n1570 (draft to C11), in paragraph 8 of 6.5.6 Additive operators:
[...] If both the pointer operand and the result [of
P + N
] 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. [...]C++ contains very similar wording (e.g. C++11, 5.7/5).
这篇关于数组指针运算 - 法律和未定义行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!