Is ++*ptr++ undefined behaviour in c++?
This
++*Ptr++;
doesn't cause U.B and is evaluated as ++(*(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 */
Note that post increments Ptr++
evaluated as
Ptr;
/* Ptr doesn't change here itself in same expression */
Ptr = Ptr + 1;
/* in next expression, Ptr considers the incremented one */
However I suspect this is undefined behaviour since it can be both
(++*ptr)++
or++(*ptr++)
. Is it?
Not really, unlike the runtime behavior, which gives ample leeway to implementors, in C++ parsing itself follows quite strict and well-defined rules1. Indeed, looking at the precedence rules, ++*Ptr++
is actually parsed as ++(*(Ptr++))
.
This trick question instead is probably alluding to the undefined behavior of expressions such as i = ++i + ++i
, where you have a value that appears multiple times in an expression, and is subjected to a modification by a side-effect of the expression itself. Such expressions are illegal, as, unless there's some operator that sequences the side effects2, the exact moment in which they are applied is not defined, so it's undefined exactly what values i
would assume in the various points of the expression.
Still, there's no undefined behavior here, as all side effects in the expression operate on different values, which appear only once in the expression: the "inner" ++
affects Ptr
, while the outer one affects the value pointed originally by Ptr
, i.e. Ar[0]
.
++(*(Ptr++))
^^^^^____increments Ptr, returning its original value
^^^^^^^^______dereferences the original Ptr, AKA &Ar[0]
^^^^^^^^^^^^_______ increments Ar[0]
That being said, if I ever saw such an expression in a code base of ours I'd go to great lengths to find the author and make sure that this wouldn't happen again.
- If sometimes very bizarre and absurdly costly to implement. Still, there are instances of undefined behavior in the standard describing some corner cases of the parsing, but it's orders of magnitude less pervasive than "runtime" undefined behavior.
- A handy summary of those rules can be found here; interestingly, some extra guarantees have been added in C++17.