数组指针算法-合法和未定义的行为 我问自己,这些代码行是否可以在C和C++中产生未定义的行为。 我试图回答每一点,阅读标准中关于数组订阅的内容(C 6.5.6-8)。我没有发布整个段落,因为它相当长
此外,如果表达式数组指针算法-合法和未定义的行为 我问自己,这些代码行是否可以在C和C++中产生未定义的行为。 我试图回答每一点,阅读标准中关于数组订阅的内容(C 6.5.6-8)。我没有发布整个段落,因为它相当长,c++,c,arrays,pointers,undefined-behavior,C++,C,Arrays,Pointers,Undefined Behavior,此外,如果表达式p指向最后一个 数组对象的元素,表达式(P)+1指向 数组对象,如果表达式Q指向数组对象的最后一个元素的后面, 表达式(Q)-1指向数组对象的最后一个元素。如果两个指针 操作数和结果指向同一数组对象的元素,或超过最后一个的元素 数组对象的元素,求值时不应产生溢出;否则 行为是未定义的。如果结果指向数组>对象的最后一个元素的前面一个元素,则 不得用作已计算的一元*运算符的操作数 我认为相同的aswers应该对C有效++ 这些行是否在C和C++中有效,我是否误解了标准?< /p> <
p
指向最后一个
数组对象的元素,表达式(P)+1
指向
数组对象,如果表达式Q
指向数组对象的最后一个元素的后面,
表达式(Q)-1
指向数组对象的最后一个元素。如果两个指针
操作数和结果指向同一数组对象的元素,或超过最后一个的元素
数组对象的元素,求值时不应产生溢出;否则
行为是未定义的。如果结果指向数组>对象的最后一个元素的前面一个元素,则
不得用作已计算的一元*
运算符的操作数
我认为相同的aswers应该对C有效++
这些行是否在C和C++中有效,我是否误解了标准?< /p> < p> 6和7都不有效,因为它们不在现有数组(包括结束指针的一个)内执行指针运算。其他一切基本上都是正确的
仅在C中:假设a[i]
与*(a+i)
相同,&*p
始终只是p
,而不计算*p
,那么5应该总是可以的,尽管C89没有指定这一点,并且这只是在C99中添加的,但您是对的。(这在C++中是不正确的,操作符可以重载,并且没有提到组合<代码>和<代码>和<代码> */COD>)< /P>
从n1570(草稿到C11),在6.5.6加法运算符第8段中:
[…]如果指针操作数和[ofp+N
]的结果都指向同一数组对象的元素,或者指向数组对象的最后一个元素,则计算不应产生溢出;否则,行为是未定义的。[……]
C++包含非常相似的措辞(例如C++ 11,5.7/5)。< /p> @ KerrekSB是C和C++中有效的这些行,我误解了标准吗?6和7是C中的UB。我不认为5是UB,但是我不知道古标准,所以它可能是。@丹尼尔费舍尔7是定义良好的行为。它将15*sizeof(int)添加到表示指针的整数中。指针无效,但操作无效。@CrazyCasta 6.5.6(8):“如果指针操作数和结果都指向同一数组对象的元素,或者超过数组对象最后一个元素的元素,则求值不应产生溢出;否则,行为未定义。”,强调我的。它不是实现定义的。没有定义。历史上,这允许分段内存模型。现代意义在于,它允许实现捕获无效的指针算法,以增加开销为代价提供额外的安全性。6:是的,确实如此。7:G是一个指针,它不改变任何东西,而在C99和以后允许5,我不认为C++在这里努力收敛到C。@ CleyMAM:<代码> G+15 < /Cord>不是一个有效的指针,因为<代码> G < /C>不是指向至少十五个INTS数组的第一个元素的指针。(感谢Luc为我做的粘贴比赛。)@CrazyCasta:不,指针算法只在数组中定义,包括一个超过末尾的数组<代码>g+15未定义。
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