Re: How bad it is to dereference a null pointer
On Oct 2, 4:56 pm, JaredGrubb <jared.gr...@gmail.com> wrote:
On Oct 1, 6:59 am, Goran <goran.pu...@gmail.com> wrote:
[...]
The question then becomes whether calling a member function
on a null object __pointer__ counts as dereferencing the
__pointer__ (problem being, I would think, that the mere
__presence__ of a * or a -> does not count as dereferencing
it, e.g. with sizeof or offsetof).
In the past (I'm not sure about C++0x), calling a non-static
member function (the expression o.f()) involves evaluating the
expression to the left of the dot. If a -> is used, it is the
equivalent of (*p).f(), so *p is evaluated (if the entire
expression is evaluated). The result of *p is an lvalue, which
must refer to an object or a function---otherwise, the behavior
is undefined.
This undefined behavior only occurs if the expression is
"evaluated". Expressions which are operands of sizeof, for
example, are never evaluated; nor are expressions in a flow path
which is never executed. (In some ways, this can be considered
"run-time" undefined behavior. A compiler can't refuse to
compile code which contains it unless it can prove that the code
will be executed for all possible input.)
Sorry about the confusion.
First, "0" is a valid memory address and is not treated
differently by the compiler.
A "null constant expression" converts to a pointer which is
guaranteed not to point to a valid object. The expression "0"
is a null constant expression. And the compiler is required to
treat it differently.
For example, here's a write-up on how you can make Linux
create an object at address 0, and then you can write to it
and call it and whatever else you want to do.
http://blog.ksplice.com/2010/03/null-pointers-part-i/
The author of the article doesn't seem to know C (or C++). But
the issue is irrelevant with regards to C++ -- when you start
playing games with specific system functions, you enter into the
realm of undefined behavior.
There is nothing special about "0";
There is according to the language standard.
most OS/architectures/runtime environments will not allocate
objects at 0 because it's incredibly "helpful" to have our
programs crash when they pretend to have objects at 0 -- in
almost every case, this is a programming error and bad things
are going to happen.
Most OS's today will arrange things so that the null pointer
constant 0 can be the address 0; it makes things a lot easier
for the compiler. But that's neither here nor there.
Second, sizeof and offsetof do not dereference anything; they
compute values from *types*.
The expressions in sizeof and typeof (if the type is not
polymorphic) are not evaluated, so there is no problem. The
macro offsetof doesn't even take a pointer, so there's no way of
giving it a null pointer.
--
James Kanze