我在测试中被问到以下有关评估++ * ptr ++
的问题(我不想自己写。测试问了它。我仍然知道它的错误代码)int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ;
int *Ptr = Ar ;
cout<<++*Ptr++ ;
但是,我怀疑这是未定义的行为,因为它可以是(++*ptr)++
或++(*ptr++)
。
是吗?我不太熟悉文档,所以找不到任何东西。
答案 0 :(得分:75)
但是我怀疑这是未定义的行为,因为它可以是
(++*ptr)++
或++(*ptr++)
。是吗?
与运行时行为(为实现者留有足够的余地)不同,在C ++中,解析本身遵循非常严格且定义明确的规则 1 。实际上,查看precedence rules时,++*Ptr++
实际上被解析为++(*(Ptr++))
。
该技巧问题可能暗示着诸如i = ++i + ++i
之类的表达式的未定义行为,其中您的值在表达式中多次出现,并由于其副作用而被修改。表达本身。这样的表达式是非法的,因为除非有一些运算符对副作用 2 进行排序,否则未定义应用它们的确切时间,因此尚不确定i
的假定值是什么。在表达式的各个方面。
仍然,这里没有未定义的行为,因为表达式中的所有副作用都作用于不同的值,这些值仅在表达式中出现一次:“内部” ++
影响Ptr
,而外部一个会影响Ptr
最初指向的值,即Ar[0]
。
++(*(Ptr++))
^^^^^____increments Ptr, returning its original value
^^^^^^^^______dereferences the original Ptr, AKA &Ar[0]
^^^^^^^^^^^^_______ increments Ar[0]
话虽这么说,如果我在我们的代码库中看到过这样的表达,我会竭尽全力寻找作者,并确保不会再发生这种情况。
答案 1 :(得分:23)
此
++*Ptr++;
不会导致U.B,并且被评估为++(*(Ptr++))
ptr++;
/* address post incremented i.e doesn't change here itself */
*ptr;
/* dereference same address i.e value at location where ptr earlier pointed i.e 6 */
++*ptr;
/* value changed where ptr pointed i.e Ar[0] becomes 7 */
请注意,帖子增量Ptr++
的估算值为
Ptr;
/* Ptr doesn't change here itself in same expression */
Ptr = Ptr + 1;
/* in next expression, Ptr considers the incremented one */