Re: Knowing the implementation, are all undefined behaviours become
implementation-defined behaviours?
On Feb 14, 1:54 pm, Robert Fendt <rob...@fendt.net> wrote:
And thus spake Ben Bacarisse <ben.use...@bsb.me.uk>
Sun, 14 Feb 2010 13:41:23 +0000:
gcc does exactly that (with certain options). I think this
is the nature a recent Linux kernel
bug:http://lkml.org/lkml/2009/7/6/19
It certainly looks that way. That's a nasty bugger to spot.
Either the pointer can be null, or it cannot. If it can be
null, the first unit test which tests it with null should cause
a crash. If it cannot, then the test the g++ would have
removed is superfluous, and removing it shouldn't change
anything.
There are many other cases of undefined behavior which do affect
optimizations, however. Consider an expression like: f((*p)++,
(*q)++). Given this, the compiler "knows" that p and q do not
reference the same memory (since if they did, it would be
undefined behavior), which means that in other code in the
function, the compiler might have cached *p, and knows that it
doesn't have to update or purge its cached value if there is a
write through *q.
Given the cross-post, I should say that I have no idea if
gcc does this for the exact case you cite (which is C++) but
I wanted to point out that similar things are done.
Yes, I did not notice this whole thread had been crossposted
to comp.lang.c; a more appropriate example would then have
been a sizeof(*pointer) or something. Since sizeof in that
case relies only on static type information, one could assume
it should work whether the pointer is null or not. But the
dereference itself already makes the whole programm ill-formed
(in case of a nullpointer).
Dereferencing a null pointer is only undefined behavior if the
code is actually executed. Something like sizeof(
f(*(MyType*)0) ) is perfectly legal, and widely used in some
template idioms (although I can't think of a reasonable use for
it in C).
--
James Kanze