In some of the answers/comments there has been a discussion about the meaning of 'undefined behavior' and whether that makes the program invalid. So I'm posting this rather long answer detailing exactly what the standard says with some notes. I hope it's not too boring...
The quoted bits of the standard come from the current C++ standard (ISO/IEC 14882:2003). There's similar wording in the C standard.
According to the C++ standard, modifying a value more than once within a set of sequence points results in undefined behavior (section 5 Paragraph 4):
Except where noted, the order of
evaluation of operands of individual
operators and subexpressions of
individual expressions, and the order
in which side effects take place, is
unspecified.53) Between the previous
and next sequence point a scalar
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 requirements of this
paragraph shall be met for each
allowable ordering of the
subexpressions of a full expression;
otherwise the behavior is undefined.
[Example:
i = v[i++]; // the behavior is unspecified
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
—end example]
Note that the second example, "i = 7, i++, i++;
" is defined since the comma operator is a sequence point.
Here's what the C++ standard says 'undefined behavior' means:
1.3.12 undefined behavior [defns.undefined]
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this
International Standard imposes no requirements. Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition of behavior. [Note: permissible undefined
behavior ranges from ignoring the situation completely with unpredictable results, to behaving during
translation or program execution in a documented manner characteristic of the environment (with or without
the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a
diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. ]
In other words, the compiler is free to do whatever it wants, including
- spitting out an error message,
- doing something implementation defined & documented,
- having completely unpredictable results
The second item covers language extensions which most compilers have, but of course are not defined in the standard.
So I guess that strictly speaking something that exhibits undefined behavior is not 'illegal', but in my experience whenever there's been something in a C/C++ program that exhibits 'undefined behavior' (unless it's an extension) - it's a bug. I think that calling such a construct illegal is not confusing, misleading, or misguided.
Also, I think trying to explain what the compiler is doing to reach the value 14 is not particularly helpful, as that misses the point. The compiler could be doing almost anything; in fact, it's likely that the compiler may reach a different result when it's run using differing optimization options (or may produce code that crashes - who knows?).
For those who want some additional references or an appeal to authority, here are some pointers:
Steve Summit's (maintainer of the comp.lang.c Frequently Asked Questions) long, long answer on this topic from 1995:
- http://www.eskimo.com/~scs/readings/undef.950321.html
Here's what Bjarne Stroustrup has to say on the matter:
- http://www.research.att.com/~bs/bs_faq2.html#evaluation-order
Footnote: the C++ standard uses the word 'illegal' exactly once - when describing a difference between C++ and Standard C regarding the use of static
or extern
with type declarations.