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 to NULL
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**
We can directly assign the pointer variable to 0 to make it null pointer.
There's no such thing as "null pointer exception" in C++. The only exceptions you can catch, is the exceptions explicitly thrown by throw expressions (plus, as Pavel noted, some standard C++ exceptions thrown intrinsically by standard operator new , dynamic_cast etc). There are no other exceptions in C++.
free() is a library function, which varies as one changes the platform, so you should not expect that after passing pointer to this function and after freeing memory, this pointer will be set to NULL.
What will we not do with function pointers? Explanation: As it is used to execute a block of code, So we will not allocate or deallocate memory.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With