Topic: Question about null pointer value conversions and static_cast


Author: ta0kira@yahoo.com (ta0kira)
Date: Thu, 17 Jun 2004 17:16:05 +0000 (UTC)
Raw View
anti_spam_email2003@yahoo.com (Me) wrote in message

news:<682764f7.0406151336.4c0eddde@posting.google.com>...
> struct Base_ { ... };
> struct Deriv : Base_ { ... };
>
> void *nullp = 0;
>
> Are the following all guaranteed to return true?
>
> static_cast<Base_*>(static_cast<Deriv*>(nullp)) == (Base_*)0;
> static_cast<Deriv*>(static_cast<Base_*>(nullp)) == (Deriv*)0;
> static_cast<Base_*>((Deriv*)0) == nullp;


NULL does not have to be 0; it only has to be a value that is guaranteed to
never point to any part memory.  On that principle alone, I don't think the
above is guaranteed.


If Base_ is a virtual base class of Deriv this would probably be undefined
because AFAIK static casting to a virtual base class does not return the same
pointer value, therefore the new value must be deduced from the underlying
object, or by an offset associated with the given type.  For example, if you
were to do this:

class BASE {};

class DERIVE : virtual public BASE {};

//...

DERIVE OBJECT;

//Then:

static_cast <BASE*> (&OBJECT) != (BASE*) &OBJECT;


If the above does not work for an actual object, then it should be undefined
when using NULL.  I think it should be undefined regardless of if the base class
is virtual just on principle: any pointer to other than a function or class
member is convertible to void*, however converting a void* back to a type other
than the actual static type of the object pointed to by the literal value of the
pointer and then casting to a further incorrect type should not be valid in any
case.  NULL does not have a type, therefore it should not be valid.
ta0kira

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: news@copro.org (Malte Clasen)
Date: Thu, 17 Jun 2004 20:42:00 +0000 (UTC)
Raw View
ta0kira wrote:
> NULL does not have to be 0; it only has to be a value that is guaranteed to
> never point to any part memory.

TC++PL (5.2) says:

"No object is allocated with the address 0. Consequently, 0 acts as a
pointer literal, indicating that a pointer doesn't refer to an object.
In C, it has been popular to define a macro NULL to represent the zero
pointer. Because of C++'s tighter type checking, the use of plain 0,
rather than any suggested NULL macro, leads to fewer problems. If you
feel you must define NULL, use

const int NULL=0;"

I guess this implies that NULL (as defined in <cstddef>) has to be 0.

Malte

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Fri, 18 Jun 2004 15:58:48 +0000 (UTC)
Raw View
news@copro.org (Malte Clasen) wrote in message news:<2jea32F10me89U1@uni-berlin.de>...
..
> I guess this implies that NULL (as defined in <cstddef>) has to be 0.

Not quite; it only has to be an integer constant expression with a
value of 0. There's no obvious reason in C++ why it should be #defined
as anything other than '0'. However, it's perfectly legal to define it
as 0x0, or 0U, or 0L, or '\0', or (5-5), or
_Implementation_Specific_Namespace::_Special_Class::_Static_Const_Member.
Note: due to Koenig lookup rules, that latter definition would bring
all of the names declared in _Implmentation_Specific_Namespace and
_Special_Class into play; this is probably not desireable.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Fri, 18 Jun 2004 18:12:26 +0000 (UTC)
Raw View
ta0kira@yahoo.com (ta0kira) wrote in message news:<b5c14083.0406170135.3da125f6@posting.google.com>...
> anti_spam_email2003@yahoo.com (Me) wrote in message
>
> news:<682764f7.0406151336.4c0eddde@posting.google.com>...
> > struct Base_ { ... };
> > struct Deriv : Base_ { ... };
> >
> > void *nullp = 0;
> >
> > Are the following all guaranteed to return true?
> >
> > static_cast<Base_*>(static_cast<Deriv*>(nullp)) == (Base_*)0;
> > static_cast<Deriv*>(static_cast<Base_*>(nullp)) == (Deriv*)0;
> > static_cast<Base_*>((Deriv*)0) == nullp;
>
>
> NULL does not have to be 0; it only has to be a value that is guaranteed to
> never point to any part memory.  On that principle alone, I don't think the
> above is guaranteed.

NULL is required to be a null pointer constant (NPC). An NPC must be
an integer constant expression with a value of 0. An NPC is not
allowed to be a pointer, since a pointer doesn't qualify as an integer
constant expression.

In any event, his code makes no use of NULL, so I'm not sure why you
brought it up. It does make use of "0". When an NPC (such as NULL or
"0") is converted to a pointer type, the result is guaranteed to be a
null pointer. All null pointers of the same type are guaranteed to
compare equal, regardless of their representation. The tricky issues
involve the conversions applied to nullp, not the ones applied to "0".

> If Base_ is a virtual base class of Deriv this would probably be undefined

"probably"? If your conclusion is correct, you should be able to cite
text from the standard supporting your point; you shouldn't have to
guess. I'd recommend getting a copy of the standard, if you're going
to make a habit of posting answers on this newsgroup.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: anti_spam_email2003@yahoo.com (Me)
Date: Tue, 15 Jun 2004 21:56:42 +0000 (UTC)
Raw View
struct Base_ { ... };
struct Deriv : Base_ { ... };

void *nullp = 0;

Are the following all guaranteed to return true?

static_cast<Base_*>(static_cast<Deriv*>(nullp)) == (Base_*)0;
static_cast<Deriv*>(static_cast<Base_*>(nullp)) == (Deriv*)0;
static_cast<Base_*>((Deriv*)0) == nullp;

It doesn't look like defined behavior to me in my reading of 5.2.9 and
4.10. This seems weird to me because T * converts to void * via
static_cast but void * converts to T * via reinterpret_cast when using
the C-style casts. So I must be missing something here.

5.2.9#6 mentions clause 4. 4.10#2 doesn't mention null pointer value
conversions.
5.2.9#10 could imply that the null pointer value is converted but it's
not explicit about it like the other casts in clause 5.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]