C++ – Is it possible to make nonnull become part of C++ type system

cnull

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 as const, which can only be placed after the * in a declaration.
  • All pointers obtained by & operator is __nonnull.
  • A __nonnull pointer value or const reference can be automatically converted to a normal pointer, but not vice-versa without a cast. (T *__nonnull can be converted to T *, and T *__nonnull & can be converted to T *const &)
  • Writable references of pointers cannot be automatically converted between normal and __nonnull (T *__nonnull & CANNOT be converted to T *&), 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 really NULL, the behaviour is undefined.

  • Assigning a null-pointer constant 0, NULL and nullptr 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 on NULL.
  • 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

Is the above proposal viable?

No.

First, it doesn't work for user-defined types. Whereas const does. Even volatile 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 not unique_ptr).