Re: Undefined behaviour [was Re: The D Programming Language]
Andrei Alexandrescu (See Website For Email) wrote:
David Abrahams wrote:
"James Kanze" <james.kanze@gmail.com> writes:
Ian McCulloch wrote:
David Abrahams wrote:
There's no reason in principle that a C++ system couldn't be
written that immediately detects way, _way_ more of the errors
that lead to undefined behavior and invokes a debugger
immediately. Every pointer dereference could be fully checked,
for example.
Right - and there are systems that already do this. Valgrind (
http://www.valgrind.org/) springs to mind at this point. In the face of a
programming error, you want as much `undefined' behaviour as possible, to
give the tools that detect such behaviour the most information possible.
Except that you only need such tools because of the undefined
behavior.
Completely backwards. You can only _use_ such tools because of the
undefined behavior. You still need something to detect the incorrect
logic that in C++ would have caused UB and in Java causes
who-knows-what "defined" behavior. But no such tool exists, or can
exist.
I'm not sure I figure the logic. Java statically disallows a number of
programs that in C++ are allowed and would be correct. It also disallows
statically a number of programs that in C++ are allowed, and that are
not correct. Now, for a _subset_ of the latter (incorrect) programs,
there are tools to help. This is my understanding of the situation. From
these facts, I fail to draw more interesting conclusions than (1) there
are programs accessible to C++ that aren't accessible to Java, and (2)
C++ is more dangerous than Java.
Just for the record, you missed one important category: Java
defines some things so that programs which would be incorrect in
C++ are correct in Java. Consider the classical example:
typedef std::auto_ptr< Doh > Ptr ;
f( Ptr( new Doh ), Ptr( new Doh ) ) ;
In Java, you don't need the smart pointers, and this code is
correct. In C++, not only do you need some sort of smart
pointers, but as it stands, the code is incorrect, and can leak
memory. The code here, in itself, doesn't contain what the C++
standard calls undefined behavior. It's still incorrect,
however, and off hand, I don't know of a tool which will detect
it. (And as far as I'm concerned: the standard doesn't tell me
whether it will leak or won't, so it's "undefined" as far as I'm
concerned---the standard doesn't specify what will happen if one
of the new expressions throws.)
Note that in Java, it's not just garbage collection which makes
this code correct. You KNOW that if the second new expression
throws, the first has completely executed. If you have
something like:
g( ++ i, new Doh() ) ;
you know that if the new expression throws, i will have been
incremented.
IMHO, those are important guarantees. If we take the call to
f(), above, the code will work with the compilers I use, using
the optimization flags I normally use. Which means that no
post-compilation tool will detect the error.
[...]
Right. The question is, does the elimination of UB (which, remember,
is a *response* to programming errors, not a cause) actually in and of
itself make it harder to make programming errors? I don't see how it
could.
I think I can answer that one.
Fewer programs are allowed. So if the language designer took the right
turns, many "wrong" programs would be statically eliminated, and few
"good" programs. So by simple set theory, we could infer under these
assumptions that fewer programming errors will make it.
I don't see how anyone could argue that changing undefined
behavior into a required diagnostic could not be an improvement.
Or giving the program correct defined behavior, as above.
I understand David's point that some forms of UB can be
exploited by the implementation to give better error handling.
Sort of, at least... C (and C++) very carefully worded the
standard to allow array bounds checking, by making a number of
things that typically work undefined behavior (where they
weren't undefined behavior in typical pre-standard C). Still,
requiring a program crash (as defined behavior) in case of an
array bounds error would have been even less error prone.
(There are very valid reasons why C and C++ could not go this
route. But increased error checking or making programs easier
to debug is definitly not one of them.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]