Topic: Null pointer constant, part 2


Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/10/30
Raw View
David R Tribble <david.tribble@central.beasys.com> writes:

> After letting the dust settle concerning my suggestion about introducing a
> new '__null' identifier into the C and C++ languages, I've come to some
> conclusions.
>
> (A) I have revoked my suggestion for '__null' for the C language.  C doesn't
> need a reserved identifier since it can use '((void*)0)', which meets just
> about all of the requirements for a null pointer constant.
>
> (B) C++, however, cannot use '((void*)0)' [and the ISO committee rejected
> James Kanze's proposal for allowing '((void*)0)' for null], so it still
> needs a null reserved identifier.
>
> So I am still a strong advocate of '__null' for the C++ language.

In a complete proposal for C++ you must define the behaviour of
C++ specific tools with __null:

- what is the type of __null:
  - what is typeid (__null)
  - what happens if a template is instantiated with the type
    of __null ?

- what is the rank of the __null to pointer convertion ?
  - what are the interraction with other conversion sequences ?

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/10/31
Raw View
Valentin Bonnard <bonnardv@pratique.fr> asked:
> In a complete proposal for C++ you must define the behaviour of
> C++ specific tools with __null:
>
> - what is the type of __null:
>  - what is typeid (__null)?

[Note: The name has been changed to '__null__' to conform to the
(apparent) ISO C naming rule for reserved identifiers.]

I would think 'typeid(__null__)' returns a value that compares unequal to
the value of 'typeid(T)' for any valid type 'T' within a given program
(execution unit).  However, it always evaluates to the same value within a
given program, so that 'typeid(__null__) == typeid(__null__)' is always
true.

>  - what happens if a template is instantiated with the type of __null?

Using '__null__' as a type parameter for a template class or template
function or is illegal, since '__null__' effectively has no discernable
type by itself.  (But note that 'sizeof(__null__) == sizeof(void *)' is
always true.)

If this seems like a limitation (I can see where it might be useful to
call a template function with an arg of '__null__'), we either state that
'__null__' requires an explicit cast (to embue it with a specific type),
or we allow a bare '__null__' to have type 'void *' or 'const void *' in
these situations.  I prefer requiring an explicit cast, which is how
'__null__' is presently defined.

> - what is the rank of the __null to pointer convertion ?
>  - what are the interraction with other conversion sequences ?

I'm not sure I understand what you mean by "rank".  Any legal use of the
'__null__' identifier requires it to be converted into a specific pointer
type.  The conversion is a single conversion and not a series of
conversions.  (For example, 'const char *cp = __null__;' causes '__null__'
to be converted into a null pointer constant of type 'const char *' in
a single step, rather than as two conversions.)  Perhaps someone can
provide an example where there might be an ambiguity in the converted
type of '__null__'?

The type of '__null__' can always be deduced from the context in which it
appears.  If it can't, then it's being used in an illegal context.

[Latest revision is at <http://www.flash.net/~dtribble/text/c9xnull.txt>.]

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David R Tribble <david.tribble@central.beasys.com>
Date: 1997/10/30
Raw View
After letting the dust settle concerning my suggestion about introducing a
new '__null' identifier into the C and C++ languages, I've come to some
conclusions.

(A) I have revoked my suggestion for '__null' for the C language.  C doesn't
need a reserved identifier since it can use '((void*)0)', which meets just
about all of the requirements for a null pointer constant.

(B) C++, however, cannot use '((void*)0)' [and the ISO committee rejected
James Kanze's proposal for allowing '((void*)0)' for null], so it still
needs a null reserved identifier.

So I am still a strong advocate of '__null' for the C++ language.

I have made a few adjustments to the original suggestion.  (See the latest
version at <http://www.flash.net/~dtribble/text/c9xnull.txt>.)

(1) I changed the name to '__null__'.  This follows the naming convention
that was (apparently) established by the ISO C committe for reserved
identifiers (e.g., '__func__', described in section 6.1.2.7 of the C9X
draft).  (As I mentioned before, the actual name is not that important,
since programmers will still use 'NULL', which should simply be #defined
to the actual null name.)

(2) Can '__null__' be passed as a varargs argument to a varargs function?
If so, what is its type?

My first impulse was to say 'yes, of course it can'.  But then we get
into the type problem.  So I made this amendment:

    The '__null__' identifier can be passed as an argument to a function
    taking a variable number of arguments (i.e., the function has a '...'
    in its prototype), and as such is passed as a null pointer constant of
    type 'pointer to void'.  Attempting to access the value of the argument
    as any other type (using the 'va_arg()' macro in the called function)
    is undefined behavior.  Passing a null pointer value of any other type
    of (variable) argument without an explicit cast to the appropriate
    pointer type is undefined behavior.

This allows a bare '__null__' to be passed as a '...' arg as if it were
being passed as '(void*)0'.  It also leaves the door open for
implementations to allow a bare '__null__' to be passed as any other
pointer type (such as 'char*', which has the same alignment restrictions
as 'void*') without requiring a cast, but note that this is 'undefined
behavior' and is thus not portable; the portable (and safe) thing to do
is to explicitly cast '__null__' to the right pointer type.  (Though I'm
not sure whether it should be 'undefined' behavior or just 'implementation-
defined'.)

(3) [From fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)]
A '__null__' cannot be used to initialize a reference argument in
a call to a function or constructor.  But can it be used to initialize a
const reference argument (so that the reference refers to a const null
pointer)?

Good question.  I can't find a problem with allowing this (in effect
initializing the reference to refer to a const null pointer).  But it
means adding a special case use for '__null__' (a situtation where integer
zero cannot be used today).  So I'm not sure.

-- David R. Tribble, david.tribble@noSPAM.central.beasys.com --
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]