Question based on discussion answer about sizeof NULL
.
Here are the snippets of the standard:
An integer constant expression with the value 0 , or such an expression cast to type
void *
, is called a null pointer constantNULL which expands to an implementation-defined null pointer constant
It seems that it is not forbidden to make #define NULL 0
instead of #define NULL ((void *) 0)
, as it is done in pros. Then it turns out that sizeof NULL
is equal to either sizeof (void *)
or sizeof (int)
(in the variant sizeof 0
).
However, @Vlad from Moscow asserts that NULL in C must be a pointer.
NULL is defined as a pointer in C.
The words “cast to type void *” are key in this quote.
Here
or
is not related to the typecasting, but to the form of the expression. And this is how NULL is defined.
So is it okay for C (no pluses) to have?
# define NULL 0
And, if applicable, why is it used in compilers
# ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *) 0)
#endif
#endif
instead of the simpler null for both languages?
After all, C didn’t even have function overloading to break something.
Answer 1, authority 100%
After looking closely at the C standard, I think you are correct. null pointer constant is either an integer constant expression with a value of 0, or such an expression cast to the type void *
.
Therefore, the definition of the NULL
macro can, in principle, be different, depending on the compiler implementation. That is, nowhere in the C standard did I find that the NULL macro must be defined as
(void *) 0
I looked into the Rationale for International Standard— Programming Languages— C document and found the following (7.17 Common definitions)
25 NULL can be defined as any null pointer constant. Thus existing
code can retain definitions of NULL as 0 or 0L, but an implementation
may also choose to define it as (void *) 0. This latter form of
definition is convenient on architectures where sizeof (void *) does not
equal the size of any integer type.
Since null pointer constant is converted in expressions to null pointer , and the size of null pointer
may not be equal to the size of any integer type, it is more convenient to define null pointer constant
as
(void *) 0
that is, immediately cast it to the type of a pointer.
In C++, this definition was abandoned, because, unlike C, in C++, due to the provision of type safety, an explicit casting of a pointer to void
to the type of a pointer to a specific object is required. That is, if null pointer constant
NULL
is defined in C++ as
(void *) 0
then you have to do explicit casting of pointers, like, for example,
int * p = (int *) (void *) 0;
which, of course, is very burdensome.
Therefore, in C++ Refused to declare NULL
as an integer constant cast to the type void *
.