Can I reliably set a function pointer to NULL in C and C++?
int (*pfun) (void) = NULL;
It is actually valid.
The C rules of assignment says that:
(Note that's an initialization here but the same type of constraints and conversions as for simple assignment apply.)
(C99, 6.5.16.1 Simple assignment p1 Constraints) "One of the following shall hold: [...] — the left operand is a pointer and the right is a null pointer constant;"
and
(C99, 7.17p3) "The macros are NULL which expands to an implementation-defined null pointer constant;"
So assigning a null pointer constant to any pointer (object pointer, function pointer or void *
) is allowed by C. Note that Plauger's book refers to C89 when he mentions Standard C but the wording of the assignment constraints are the same in C89.
![rationalcoder](https://i.stack.imgur.com/QjLl7.jpg?s=256&g=1)
rationalcoder
I love most things computer science. I write code every day for fun or for my day job.
Updated on June 05, 2022Comments
-
rationalcoder about 2 years
In P.J. Plauger's book, The Standard C Library, he warns about assigning a function pointer to NULL.
Specifically, he says this:
The macro NULL serves as an almost-universal null pointer constant. You use it as the value of a data-object pointer that should point to no data object declared (or allocated) in the program. As I mentioned on page 216, the macro can have any of the following definitions 0, 0L, or (void *)0.
The last definition is compatible with any data object pointer. It is not, however, compatible with a function pointer. That means you cannot write
int (*pfun) (void) = NULL; /* WRONG */
The translator may complain that the expression type is incompatible with the data object you wish to initialize.
He goes on to say that:
...There is no guarantee, however, that a pointer to void has the same representation as any other (non-character) pointer. It isn't even assignment compatible with function pointers. That means that you can't write NULL as a universal null-pointer constant. Nor can you safely use it as an argument expression in place of an arbitrary data-object pointer.
I have been assigning function pointers to
NULL
for quite some time without any problems, and I am wondering if it isn't portable.Specifically:
void (*test)() = NULL
=> compiles fine with both gcc and g++void (*test)() = 0
=> compiles fine with both gcc and g++void (*test)() = (void*)0
=> produced an invalid conversion error in both gcc and g++EDIT:
void (*test)() = (void*)0
compiles fine in gcc, I was using a file with a .cpp extension... Still, will it always compile, despite Plauger saying that assigning a function pointer toNULL
is wrong?The part I don't understand is the definition of NULL in my stddef.h:
#if defined (_STDDEF_H) || defined (__need_NULL) #undef NULL /* in case <stdio.h> has defined it. */ #ifdef __GNUG__ #define NULL __null #else /* G++ */ #ifndef __cplusplus #define NULL ((void *)0) // this line confuses me #else /* C++ */ #define NULL 0 #endif /* C++ */ #endif /* G++ */ #endif /* NULL not defined and <stddef.h> or need NULL. */ #undef __need_NULL
This seems to be defining
NULL
to be 0 in C++ and ((void *)0) in C. Is it really, or is it being defined as __null?If so, why does assigning to
NULL
work all the time, even though assigning to (void*)0, according to Plauger, is "wrong"?**I am interested in C89**