In C23, the nullptr
keyword got standardized. I would prefer to use nullptr
instead of NULL
prior to C23 too because it means that I could write code which compiles in:
I could simply use NULL
in both languages and every C standard, but that would be highly unusual in C++ code, and nullptr
is becoming the norm in both languages anyway.
As far as I know, you are not allowed to use #define
to replace keywords in the language, and that may cause problems when defining a compatibility macro. Basically, I need:
// only if this is neither C++ nor C23
#define nullptr /* something */
How can I properly define this macro?
Some things of note:
__STDC__
and __STDC_VERSION__
were added in "C95" (the addendum to ISO C 9899:1990).nullptr
using pre-processor conditionals because it is not a macro.stddef.h
or equivalent header even when using a conforming C23 compiler so don't assume that this one is #included.-std=c2x
which does contain nullptr
but sets __STDC_VERSION__
to a placeholder value 202000L.nullptr
since it was added in C++11.Therefore the macro checks should look something like this:
/* C++11 or later? */
#if (defined(__cplusplus) && __cplusplus >= 201103L)
#include <cstddef>
/* C2x/C23 or later? */
#elif ( defined(__STDC__) && \
defined(__STDC_VERSION__) && \
(__STDC_VERSION__ >= 202000L) )
#include <stddef.h> /* nullptr_t */
/* pre C23, pre C++11 or non-standard */
#else
#define nullptr (void*)0
typedef void* nullptr_t;
#endif