NULL
is the billion-dollar mistake but there is nothing in the type system of C++ to prevent it. However, C++ already has const-correctness so implementing NULL
-correctness seems trivial:
- introduce a keyword,
__nonnull
, as a specifier in the same class asconst
, which can only be placed after the*
in a declaration. - All pointers obtained by
&
operator is__nonnull
. - A
__nonnull
pointer value orconst
reference can be automatically converted to a normal pointer, but not vice-versa without a cast. (T *__nonnull
can be converted toT *
, andT *__nonnull &
can be converted toT *const &
) -
Writable references of pointers cannot be automatically converted between normal and
__nonnull
(T *__nonnull &
CANNOT be converted toT *&
), i.e.int x; int *__nonnull p = &x; int *q = p; // OK int *const &r = p; // OK int *const *s = &p; // OK int *&t = p; // ERROR, don't want to assign NULL to t int **u = &p; // ERROR, don't want to assign NULL to *u
-
const_cast
can be used to cast a normal pointer to a__nonnull
pointer, in which if the pointer is reallyNULL
, the behaviour is undefined. - Assigning a null-pointer constant
0
,NULL
andnullptr
to a__nonnull
pointer variable is an error. __nonnull
pointers cannot be default initialised, like a reference.- Have a standard library function to convert a normal pointer to a
__nonnull
pointer, which throws an exception onNULL
. - An optional warning will be given by compiler for dereferencing normal pointers without
NULL
check, which the practice is going to be deprecated.
Is the above proposal viable? Are the above things enough for a NULL
-safe type system?
Best Answer
No.
First, it doesn't work for user-defined types. Whereas
const
does. Evenvolatile
does. And with lots of smart pointer types, having it work with user-defined types is kind of important.Second, using
const_cast
to convert to__notnull
is... silly.Third, C++ is not C. If something is important enough to get a keyword in C++, then it's important enough to get a keyword that doesn't look terrible.
Fourth, this can be done adequately through a simple type. The C++ core guidelines support library provides
not_null
, which essentially has the properties you suggest. And, unlike__notnull
, it works with user-defined smart pointers too (though notunique_ptr
).