Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I reliably set a function pointer to NULL in C and C++?

Tags:

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*)0compiles 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**

like image 748
rationalcoder Avatar asked Nov 05 '15 20:11

rationalcoder


People also ask

Can you set a pointer to null?

We can directly assign the pointer variable to 0 to make it null pointer.

Does C have null pointer exception?

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++.

Does free set pointer to null?

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 Cannot be done with function pointers?

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.


1 Answers

 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.

like image 86
ouah Avatar answered Sep 25 '22 23:09

ouah