I have been asked the following question in a test (I didn't want to write it myself. The test asked it. I know its bad code still) about evaluating ++*ptr++
int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ; int *Ptr = Ar ; cout<<++*Ptr++ ;
However, I suspect this is undefined behavior since it can be both (++*ptr)++
or ++(*ptr++)
. Is it? I am not too well acquainted with documentation so I couldn't find anything.
So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.
Unspecified behavior is different from undefined behavior. The latter is typically a result of an erroneous program construct or data, and no requirements are placed on the translation or execution of such constructs.
printf("%f\n",0); Above line of code is undefined behavior.
No thread of execution can execute forever without performing any of these observable behaviors. Note that it means that a program with endless recursion or endless loop (whether implemented as a for-statement or by looping goto or otherwise) has undefined behavior.
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.
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 */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With