Rajesh said:
Can anyone tell me what is the difference between undefined behavior
and unspecified behavior?
> Though I've read what is given about them, in ISO standards, I'm still
> not able to get the difference.
Sometimes the Standard gives a list of possible behaviors
in some situation: "The behavior shall be A or B or ..." As
long as the implementation behaves in any of those ways, it
obeys the Standard. That is "unspecified behavior," meaning
that the Standard does not specify which of the possibilities
will be chosen. As an example, the Standard points out the
order of function argument evaluation: in `f( u(x), v(x) )'
it is "unspecified" whether u() is called before or after v().
Sometimes the Standard requires that the implementation
document the choice of some particular unspecified behavior.
For example, the maximum value of an `int' is unspecified, but
the implementation must "publish" that value as `INT_MAX'.
This subset of unspecified behavior is called "implementation-
defined behavior."
Sometimes the Standard imposes no requirement at all: If
the program does thus-and-such, the Standard simply washes its
hands of the matter and disclaims jurisdiction. That's what
"undefined behavior" is: When the Standard no longer rules the
course of events. For example, the effect of dividing by zero
is undefined: You might get a result like "infinity" or you
might get a completely bogus result or you might get a crash.
In principle, since the program has left the country where the
Standard is law and has entered a lawless territory, anything
can happen. You have no Constitutional rights on a desert island.
For example:
Consider the following code:
a[i++] = i;
We say that the above expression statement produces undefined
behavior. Why can't we call it as unspecified behavior, because
nothing is said about the order of completion of side effects, which
affects the output?
One intent of the Standard is to promote implementations of
C on widely differing platforms, which it does (in part) by trying
to avoid raising unnecessary barriers. Every time the Standard
requires some particular behavior, it constrains implementations
and puts a burden of obedience on them. Instead of forcing the
implementations to assign some arbitrary meaning to the dubious
statement above, the Standard leaves it undefined: Why pass a
largely useless law that might make trouble by hobbling the
(software and hardware) optimizers?
Every requirement in the Standard represents a balancing act
between usefulness and restrictiveness.
Furthermore, I've found this expression "demons out of your nose",
used by many, while talking about undefined behavior. Please tell me
what that expression means, in this context.
It was the original 1989 ANSI Standard that gave the phrase
"undefined behavior" wide currency, and since it was a new thing
people liked to play with it. A little bit of a game developed
in c.l.c. about just how "undefined" the behavior could be, and
when somebody posted code like `a[i++] = i' people would have fun
cooking up outrageous descriptions of the possible consequences.
Things started fairly tamely with descriptions of system
malfunctions: "Your hard drive will be reformatted," "Your
CPU will melt to silicon slag," and that sort of thing. The
descriptions started becoming more imaginative: "Your SPACE bar
will be charged to six million volts and electrocute you on
the spot," "Chocolate pudding will ooze from your floppy drive."
The warning that "Demons will fly out of your nose" was popular
at about the time the game of describing undefined behaviors
started to lose its appeal, and survived in memory in somewhat
the way the last Tsar remains a special figure (quick: who was
the next-to-last Tsar?). The shorthand "nasal demons" was widely
used for a while, but nowadays these fanciful descriptions of
undefined behavior are largely things of the past.
Perhaps reality has overtaken them.