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

In PJ Plauger's book, The Standard C Library, he warns about assigning a pointer to a NULL function.

In particular, he says the following:

The NULL macro serves as an almost universal null pointer constant. You use it as the value of a data object pointer, which should indicate the absence of a data object declared (or allocated) in the program. As I mentioned on page 216, a macro can have any of the following definitions 0, 0L, or (void *) 0.

The latter definition is compatible with any pointer to a data object. However, it is not compatible with a function pointer. That means you cannot write

int (*pfun) (void) = NULL; /* WRONG */

The translator may complain that the type of expression is incompatible with the data object that you want to initialize.

He goes on to say that:

... However, there is no guarantee that the void pointer has the same representation as any other (non-character) pointer. This is not even a compatible assignment with function pointers. This means that you cannot write NULL as the universal constant of a null pointer . You can also safely use it as an argument expression instead of an arbitrary data object pointer.

I have been setting pointers to NULL for some time without any problems, and I am wondering if it is portable.

In particular:

void (*test)() = NULL => compiles with both gcc and g ++

void (*test)() = 0 => compiles 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 in gcc, I used a file with the extension .cpp ... Nevertheless, will it always compile, despite the fact that Plauger says that the pointer is assigned functions on 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 

It seems that the definition of NULL is 0 in C ++ and ((void *) 0) in C. Is it really or defined as __null?

EDIT: If so, why does the NULL assignment work all the time, although assigning (void *) 0, according to Plauger, is "wrong"?

EDIT 2: I'm interested in C89

+7
c ++ c gcc pointers g ++
source share
2 answers
  int (*pfun) (void) = NULL; 

This is really true.

The assignment rules for C indicate that:

(Note that initialization is used here, but there are the same types of constraints and transformations as for simple assignment.)

(C99, 6.5.16.1 Simple assignment p1 Constraints) "One of the following values ​​must contain: [...] - the left operand is a pointer and the right operand is a null pointer constant;"

and

(C99, 7.17p3) "Macros are NULL, which expands to a null pointer constant defined by the implementation;"

Therefore, assigning a null pointer constant to any pointer (object pointer, function pointer, or void * ) is allowed by C. Note that the Plauger book refers to C89 when it mentions the C standard, but the wording of assignment restrictions is the same in C89.

+2
source share

void (*test)() = (void*)0 => produced an invalid conversion error in both gcc and g ++

GCC defines the language based on the file extension. Compiling a .cc file with GCC will call the C ++ compiler, not the C compiler.

Try using the C source file and you will see that it is accepted. As it should be, as allowed by the standard.

If so, why does the NULL assignment work all the time, but the assignment (void *) 0 is not?

NULL not allowed to be defined as ((void*)0) in C ++ mode. In C ++ mode, it should be defined as an integral constant with a value of 0 or as nullptr . Any can be converted to any type of function pointer.

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

Yes, in any appropriate C or C ++ implementation, this will work.

+7
source share

All Articles