Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-06-11 20:26:27


On Monday 11 June 2001 17:50, you wrote:
> 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"?

Shouldn't be necessary. Const-member-function is just a type, so the
pointer-to-member conversion handles it.

> > 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.

If this sort of construct comes up more often (the "ignore" in tuples, if it
still exists, is another example), perhaps it would be best to have a macro
that chooses between declaring it in an anonymous namespace (no extra work
required by the user), declaring it as extern (user links the Boost libraries
that contain the instance), or eliminating it entirely (for _really_ small
amounts of RAM).

> > 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.

It is. I only point again to Stroustrup's example:

void f(char*);
void f(int);

void g() { f(0); }

If the user had the code in "g" that is meant to call the char* version of f,
and later the new int overload is called, g's meaning has silently changed.
While this is a general problem with implicit conversion, nil is a bit more
strict in what it can be converted to.

> [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

        Doug


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