char* p = "hello"; printf(" %c %c %c %c", *p, *++p, *p++, *p);
output:
l l h h
I have read the below thread but still not able to find why the output is like " l l h h". Could anyone please answer.
char* p = "hello"; printf(" %c %c %c %c", *p, *++p, *p++, *p);
output:
l l h h
I have read the below thread but still not able to find why the output is like " l l h h". Could anyone please answer.
Because the code contains both ++p
and p++
, it attempts to modify p
twice.
These expressions appear in arguments to a function call. The C standard does not specify the order in which function arguments are evaluated.
When a program attempts to modify an object twice in an unordered way, the program is broken. The C 2011 standard says, in clause 6.5, paragraph 2, that when there are two unordered modifications to the same object, the C standard does not impose any requirements on the behavior of the program.
This means the compiler does not have to make this program work in any particular way. The compiler essentially “gives up” and does whatever it happens to do.
This invokes undefined behavior. You may get either expected or unexpected results or program crash or segmentation fault, etc.
The order of evaluation of arguments of printf
is not define. They can be evaluated in any order and causing p
to modify more than once within two sequence points. This invokes UB.
c-faq: 3.8:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
The order of evaluation is undefined, so you should not rely on side effects in one parameter being used to derive the value of another parameter.
In your example it looks like the parameters are evaluated right to left, which mirrors the calling convention of the printf
function whereby the first parameter is on the top of the stack. Methods like printf
which support variable length argument lists take advantage of this, as the compiler will emit infomration which will allow the function to walk the argument list in left-to-right order.
C supports many different calling conventions. The C calling convention pushes arguments from right to left, but the Pascal calling convention goes from left to right. Other put some parameters into registers and pass the rest on the stack. By not enforcing an order of evaluation the language give greater flexibility to compilers when handling these calling conventions.