Boost logo

Boost :

From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2001-06-11 16:50:05


Douglas Gregor wrote:
> The function library currently under review contains a type 'nil_t' with an
> instance 'nil'. It is a replacement for "0" or "NULL" in any code. The
> implementation is trivial, but it should probably be placed in its own header
> because it's usefulness extends beyond 'function'. The code is just:

If we decide to have some kind of null pointer with a separate
type, it should be in a separate header file (or possibly in utility.hpp
if simple enough). It appears to have uses in template metaprogramming
as well (end-of-tuple) (Gary).
On the other hand, the template metaprogramming usage seems to
be sufficiently different from the value-based view we have in
boost.function that these may well be two different types.

> namespace boost {
> struct nil_t

Note that POSIX reserves names with XXX_t. Not that POSIX currently
has any relationship with C++ whatsoever, but "nil_type" seems to
be more in the spirit of e.g. member typedefs of standard containers.

> template<typename T> operator T*() const { return 0; }
> template<typename T, typename U> operator T U::*() const { return 0; }

So we're actually testing template conversion operators in compilers
now. Nice :-) Do we need a special overload for "pointer-to-const-
member-function"?

> namespace {
> nil_t nil;
> }

I'd rather defer the instance to client code. The client code may
wish to avoid a variable (e.g. embedded stuff short on RAM) and use
temporaries only.

> Advantages of 'nil' over NULL:
> - NULL is not necessarily portable. Some C++ compilers pick up bad
> definitions of NULL from the system C libraries, making it useless.

18.1p4 is explicit that NULL must be a "null pointer constant", as defined
by 4.10. Any implementation not ascertaining that is non-conformant.
While the boost implementation has avoided using NULL for exactly that
issue, boost has also avoided letting implementation restrictions
influence interfaces so far. The general guideline for the
implementation would be to avoid NULL and use 0 always.

> - 0 is an integer. It converts to pointer types but doesn't convey much
> information to the user.

I disagree. "int *p = 0" is, and has been, the recommended way of
dealing with null pointers in C++ since several years, and I find it
easily to understand, easier than parsing "NULL". That's certainly
a matter of personal taste.

[reordered]
> - The type of NULL is unspecified, so it is impossible to overload a
> function based on it.
> - the type of 0 is "const int". Overloading a function to take a null value
> based on const int also allows any integer value to be passed in, and the
> error cannot be detected at compile-time.

This seems to be an issue for boost.function, where the user wants to
clear some function object with an obvious syntax. "func = 0" doesn't
work, though. The alternative is to use func.clear(), which is
incompatible with usual function pointers. This may bite with
generic programming. Or one could use func = (void(*)())0
which works, but looks slightly ugly.

I'd like to see more experience with the need to zero boost.function
objects where func.clear() is not possible. Otherwise, I'd like
to avoid the nil issue in the first round.

Jens Maurer


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk