Keith Thompson said:
Tim Rentsch said:
(e-mail address removed) (Richard Harter) writes: [...]
In short, the C standards are incomplete; they do not completely
specify the interpretation of code.
It is complete in this area. The Standard says specifically
that order of evaluation is "unspecified", meaning any ordering
that doesn't violate any other stated requirements is allowed.
One way to look at it is that
the standards specify C as a family of languages, differing by
implementation defined rules.
Certainly that is one way to look at it. A better way (IMO) to
look at it, at least as regards evaluation order, is that C
is a single language with a non-deterministic semantics. One
reason for this is that an implementation need not make the
same choice about evaluation order from one expression to the
next, or even the same on the next compilation as this one.
And for evaluation order in particular, implementations are
under no obligation to describe or document what rules they
use to determine ordering in any particular circumstance.
Did you really mean to use the word "non-deterministic"?
Yes I did, and in retrospect I may have been guilty of confusing
the issue, so let me explain further.
IME the word "non-deterministic" is used to mean one of three
different things, even though these different meanings are
related they're definitely not the same:
1. Certain algorithms or automata are described as being
"non-deterministic" to mean that, when confronted with
a choice, they make "the right" choice, or in another
way of explaining the behavior they make all possible
choices. A non-deterministic Turing machine doesn't
make a choice at random, it makes the "right" choice
or equivalently it computes in parallel all possible
alternative choices.
2. Sometimes "non-deterministic" is used to mean that
when confronted with a choice some particular choice
is made, but which choice that is is made "at random".
3. In the area of formal semantics in particular, the
term "non-deterministic" is used as an adjective
(often modifying the word semantics) to mean that
when a choice is confronted, some particular choice
is made but the semantics doesn't prescribe how
the choice is to be made. Implementing a formal
semantics that is non-deterministic could be done
by, eg, always choosing the first alternative,
always choosing the last alternative, choosing the
n%k'th choice of k alternatives on the n'th choice,
waiting for a cosmic ray and making a choice based
on the energy of the cosmic ray, etc. In some sense
meaning (3) is a generalization of meaning (2).
Since I have some background in formal semantics, I meant the
phrase "non-deterministic semantics" in the sense of meaning 3.
This meaning is pretty close to what the C standard calls
'unspecified behavior' (in fact probably identical, but I don't
want to equate a formal term and an informal term without a lot
more thought than I've put in just now).
I'd prefer to say that C is a single language whose semantics
are not entirely specified in all cases. Saying that it has
"non-deterministic semantics" could imply that each implementation
is required to behave in a non-deterministic manner, which of course
it isn't.
It does behave in a non-deterministic manner in the literal sense
of non-deterministic, that is, it is not determined by the
definition. An implementation that bases its choices on random
events that by chance always happens to take the first choice is
still "non-deterministic"; so is an implementation that simply
decided always to take the first choice available. However you
are right that it is potentially confusing, so to be explicit
and also (hopefully) clear, I will say that by "non-deterministic
semantics" I mean that an implementation may elect any choice
resolution mechanism it wishes, including both mechanisms that
are completely regular and predictable and also mechanisms that
make totally unpredictable choices, or any combination of
predictable, unpredictable, and/or "random".