N
Nick Keighley
this was originally on comp.lang.c++
but discussions about Undefined Behaviour seem on-topic to comp.lang.c
as well
this surprised me
I thought a fair amount of Undefined Behaviour was implicit.
Thta is no behaviour was defined therefore the behaviour was
undefined; rather there being an explicit statement that
"this behaviour is not defined". I'm pretty sure this is true
of C if not C++.
<snip>
but discussions about Undefined Behaviour seem on-topic to comp.lang.c
as well
[snipped discussion about run-time error when OP accessed
uninitialized memory. OP complained that C++ compiler (gcc)
could not detect this even though its warning level was set to
highest]
You seem to be taking the opinion that compilers should
catch all undefined behavior. C++ is not Java. C++'s stated
primary design goals include
- runtime performance comparable with assembly
- don't pay for what you don't use
- portable
- easy to write code / programmer productivity (with less relative
emphasis on this one IMHO)
With these design goals in mind, it is not reasonable to
expect a compiler to catch all possible undefined behavior
or errors. To do that would necessarily restrict the
language so that it's less comparable to assembly in speed
and/or you start paying for things you don't use.
That's not strictly true. Both the C and the C++ standards
were designed so that all undefined behavior can be caught.
this surprised me
At run-time, at the latest. (I think that there is some which
can't be detected at compile time. But probably a lot less than
one might think---compilers have gotten quite good at tracing
intermodular code flow.) And it's scattered throughout the
standard. Mostly in the form of "undefined behavior"---the
behavior is undefined precisely so that a checking
implementation can trap it.
I thought a fair amount of Undefined Behaviour was implicit.
Thta is no behaviour was defined therefore the behaviour was
undefined; rather there being an explicit statement that
"this behaviour is not defined". I'm pretty sure this is true
of C if not C++.
Too hard, no. Too expensive, perhaps: to catch all pointer
violations, you need "fat" pointers---each pointer contains a
current address, plus the limits, each modification of the
pointer value verifies that the current address stays in the
limits, and each access through the pointer verifies that it
isn't using the end pointer (and that the pointer isn't null,
but most hardware traps this already today).
Of course, a good compiler could eliminate a certain number of
these checks, or at least hoist them outside of a loop. But I
don't think it could easily avoid the fact that the size of a
pointer is multiplied by three, which makes things like copying
significantly more expensive, and can have very negative effects
on locality.
That's unspecified, not undefined behavior.
Takes a pointer. If the pointer contains the bounds, then it
can easily check.
<snip>