Definition of NULL

Andrew Brampton brampton+freebsd-hackers at gmail.com
Sat May 2 15:59:06 UTC 2009


I'm writing a C++ Kernel Module, and one thing that has been bugging
me is the kernel's definition of NULL.

sys/sys/_null.h (in CURRENT):

#if defined(_KERNEL) || !defined(__cplusplus)
#define NULL    ((void *)0)
#else
#if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
#define NULL    __null
#else
#if defined(__LP64__)
#define NULL    (0L)
#else
#define NULL    0
#endif  /* __LP64__ */
#endif  /* __GNUG__ */
#endif  /* _KERNEL || !__cplusplus */

>From what I've read online the definition of NULL in C is (void *)0,
whereas in C++ it should be 0, or 0L (on 64bit machines).

Now, my C++ kernel module is built with _KERNEL definited, like any
other C kernel module. This leads to NULL being defined incorrectly.

So I have a question and two suggestions. Firstly, why is the #if
defined(_KERNEL) in _null.h? Is it to stop userland application
applications picking up this definition? Or for another reason?

and two, how about we change the first line of _null.h so that we use
a && instead of a || like so:
#if defined(_KERNEL) && !defined(__cplusplus)

That should ensure the definition is correct. Or, a more radical
approach, we could remove the check for _KERNEL, since I can't figure
out why it is needed and do something like:

#if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
# define NULL    __null
#elif !defined(__cplusplus)
# define NULL    ((void *)0)
#elif defined(__LP64__)
# define NULL    (0L)
#else
# define NULL    0
#endif

That way, if we are using GCC 4+ we use their __null definition,
otherwise if we are not c++ we use the standard (void *)0, and then if
we are 64bit we use 0L, and finally anything else uses 0. A quick
amd64 kernel compile seems to allow my new definition

I hope this makes sense, and I welcome all feedback.
Andrew


More information about the freebsd-hackers mailing list