This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] C undefined behavior fix
- From: dewar at gnat dot com
- To: rth at redhat dot com, torvalds at transmeta dot com
- Cc: gcc at gcc dot gnu dot org, trini at kernel dot crashing dot org
- Date: Fri, 4 Jan 2002 21:57:51 -0500 (EST)
- Subject: Re: [PATCH] C undefined behavior fix
<<For example, people did say that "undefined behaviour" means that the
compiler is free to generate code to reformat the harddisk. That is true
from a technical standpoint, yet I think everybody agrees that a compiler
that does that is total crap.
>>
Actually it is not hard to construct examples where this sort of stuff
can happen. Once a compiler is free to form predicates based on assurances
from the standard that there is no undefined behavior, these predicates
can back propagate and cause amazing results. For example, the compiler
might decide to omit a comparison, because it can prove that if the
comparison is false, then the program executes an undefined operation.
In that case it can assume that the result of the comparison is true.
Once a comparison "malfunctions" in this way, all sorts of things could
happen in a program, up to and including unintended disk damage.
You may sit back there and say that you think a compiler that does that
is crap. I often hear people who don't understand language semantics well
say that, but I find it strange that you would say this.
The fact of the matter is that programs that execute undefined operations
are the crap. If we require compilers to do reasonable things with such
programs then
a) we are in the twilight zone of vague, impossible to define clearly
semantics, and the whole language definition becomes a mess.
b) we prevent the generation of efficient code in ways that can be
very surprising.
SO no, it is not at ALL the case hat "everybody agrees" on anything of
the kind. Undefined is undefined, it is not "undefined, not not so undefined
as to offend Linus", since the latter is not a predicate we can define.
What you need to do is to clearly define (at an appropriate language level,
i.e. the semantic level of the standard, with the same precision of language).
*EXACTLY* what semantics you want to see for undefined or implementation
defined cases (the distinction is really not very important from a pragmatic
point of view). Then we have to discuss whether it is too expensive or
impractical otherwise to make this the default, and if not, whether it is
reasonable or practical to provide an implementation option, switch, or
attribute as appropriate.
Part of the trouble with C is that early compilers were extremely naive, and
did very little optimization. On the PDP-11 you could pretty much KNOW the
sequence of assembly language. Modern C compilers and modern architectures
are a completely different world, and we really have to start taking the
C standard seriously as a semiformal semantic definition of the set of
programs whose meaning *is* well defined, and be VERY wary of any programs
outside this set.