Our class was asked this question by the C programming prof:
You are given the code:
int x=1;
printf(\"%d\",++x,x+1);
What output w
Echoing codaddict the answer is 2.
printf will be called with argument 2 and it will print it.
If this code is put in a context like:
void do_something()
{
int x=1;
printf("%d",++x,x+1);
}
Then the behaviour of that function is completely and unambiguously defined. I'm not of course arguing that this is good or correct or that the value of x is determinable afterwards.
The output will be always (for 99.98% of the most important stadard compliant compilers and systems) 2.
According to the standard, this seems to be, by definition, "undefined behaviour", a definition/answer that is self-justifying and that says nothing about what actually can happen, and especially why.
The utility splint (which is not a std compliance checking tool), and so splint's programmers, consider this as "unspecified behaviour". This means, basically, that the evaluation of (x+1)
can give 1+1 or 2+1, depending on when the update of x
is actually done. Since however the expression is discarded (printf format reads 1 argument), the output is unaffected, and we can still say it is 2.
undefined.c:7:20: Argument 2 modifies x, used by argument 3 (order of evaluation of actual parameters is undefined): printf("%d\n", ++x, x + 1) Code has unspecified behavior. Order of evaluation of function parameters or subexpressions is not defined, so if a value is used and modified in different places not separated by a sequence point constraining evaluation order, then the result of the expression is unspecified.
As said before, the unspecified behaviour affect just the evaluation of (x+1)
, not the whole statement or other expressions of it. So in the case of "unspecified behaviour" we can say that the output is 2, and nobody could object.
But this is not unspecified behaviour, it seems to be "undefined behaviour". And the "undefined behaviour" seems to have to be something that affect the whole statement instead of the single expression. This is due to the mistery around where the "undefined behaviour" actually occur (i.e. what exactly affects).
If there would be motivations to attach the "undefined behaviour" just to the (x+1)
expression, as in the "unspecified behaviour" case, then we still could say that the output is always (100%) 2. Attaching the "undefined behaviour" just to (x+1)
means that we are not able to say if it is 1+1 or 2+1; it is just "anything". But again, that "anything" is dropped because of the printf, and this means that the answer would be "always (100%) 2".
Instead, because of misterious asymmetries, the "undefined behaviour" can't be attached just to the x+1
, but indeed it must affect at least the ++x
(which by the way is the responsible for the undefined behaviour), if not the whole statement. If it infects just the ++x
expression, the output is a "undefined value", i.e. any integer, e.g. -5847834 or 9032. If it infects the whole statement, then you could see gargabe in your console output, likely you could have to stop the program with ctrl-c, possibly before it starts to choke your cpu.
According to an urban legend, the "undefined behaviour" infects not only the whole program, but also your computer and the laws of physics, so that misterious creatures can be created by your program and fly away or eat you.
No answers explain anything competently about the topic. They are just a "oh see the standard says this" (and it is just an interpretation, as usual!). So at least you have learned that "standards exist", and they make arid the educational questions (since of course, don't forget that your code is wrong, regardless undefined/unspecified behaviourism and other standard facts), unuseful the logic arguments and aimless the deep investigations and understanding.