Topic: NULL specifications (Was: What is the macro NULL according to standard C++?)
Author: Valentin Bonnard <Valentin.Bonnard@free.fr>
Date: 2000/10/22 Raw View
kanze@gabi-soft.de wrote:
> Team-Rocket@gmx.net (Niklas Matthies) writes:
>
> |> On Tue, 17 Oct 2000 18:16:31 GMT, Valentin Bonnard
> |> <Valentin.Bonnard@free.fr> wrote:
> |> > James Dennett wrote:
> |> Now what's with the null pointer constant? For convenience, you want
> |> it to be really generic, similar to singleton type.
>
> That, of course, argues for a special key word. Which is probably the
> best solution anyway. But it requires a bit of effort -- if f is a
> template function, what type should f(NULL) instantiate?
I can answer this one:
---NULL keyword specification---cut here---
None. NULL is just a NPC (null pointer constant), it has no type.
It is not a value, and does not have one (it is not an object).
typeid (NULL) is ill-formed
A NULL argument causes no template argument deduction.
Example: If foo is defined as:
template <typename T>
void foo (T*);
then foo(NULL) is ill-formed, because the template
argument T cannot be deduced.
(but foo<T> (NULL) is well-formed)
The argument NULL has no associated namespaces for the purpose
of type-dependant name lookup.
Example:
Since NULL is not an integral constant, the following is
ill-formed:
int i = NULL;
--end specification---
---NULL keyword alternative specification---cut here---
The expression NULL has type npc_t (stands null pointer
constant type).
NULL and npc_t are keywords.
The npc_t type only has one value, the null pointer constant.
(Example: it can be spelled npc_t() or NULL.) Thus any
expression of type npc_t is NPC.
npc_t is a normal complete, built-in type. It means that:
- Variables of type npc_t can be declared.
- npc_t, like other built-in types, has no associated
namespaces.
- The typeid operator can be applied to an expression
of type npc_t.
Example:
int* p = NULL;
NULL is a NPC, so it can be converted to int*, and yields
a null pointer.
Example:
assert (typeid (NULL) != typeid ((char*)NULL));
Example:
template <typename T>
void foo (T*);
foo (NULL);
foo<npc_t> (NULL);
Both statements are equivalents, and well-formed.
Example:
int i = NULL;
There is no conversion from npc_t to int, so the declaration
is ill-formed.
--end alternative specification---
> The reason that MS-DOS compilers wanted ((void*)0) was linked to the
> different memory models. Technically, passing NULL as a variadic
> argument has never worked
BTW, my proposal allows the compiler to easily diagnose uses
of NULL with variadic functions; without compiler/preprocessor
magic, this is currently impossible, since NULL is converted
to 0 or ((void*)0) before the compiler sees it.
> |> > The problem with allowing only ``integer constant expressions
> |> > with the value 0'' as null pointer constants is that the
> |> > following wouldn't be valid:
>
> |> > #define NULL ((void*)0)
> |> > static int *p = NULL;
>
> |> > which is, to say the least, annoying (and reminds me why
> |> > C isn't my favorite language).
>
> |> It's C++ that allows only ``integer constant expressions with the
> |> value 0'' as null pointer constants and makes the above code invalid
> |> in C++. If you find this annoying, then you should blame C++, not
> |> C.
>
> Actually, the above code is undefined behavior in both languages, since
> you aren't allowed to define a macro named NULL.
Even if you don't include any standard headers ?
Anyway, my point was that my example was ill-formed in a language
which isn't C nor C++. And it remains valid if you write NUL or nil
or FOOBAR instead of NULL.
--
Valentin Bonnard
---
[ 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.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]