The C standard requires that NULL be defined in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h, and wchar.h.
The C++ standard requires that NULL be defined in the c* header corresponding to each of those.
The C standard is very strict about the names a standard can define--each standard header must define precisely the names the standard requires that header to define. The only other names it can define are those that are reserved for the implementation, such as those starting with an underscore followed by another underscore or a capital letter.
The C++ standard is much more permissive in this respect--including any one standard header can have the same effect as including any or all other standard headers.
From a practical viewpoint, C++ implementations used to take quite a bit of advantage of this permissiveness--that is, including one standard header frequently defined the names from a number of other standard headers. More recent implementations tend to work more like the C standard requires, staying much closer to each header defining only the names required by to be defined by that header. They're still probably not as strict about it as the C standard requires, but much closer than they used to be (as a rule).
Answer from Jerry Coffin on Stack OverflowOld compilers and NULL
What header defines NULL in C++? - Stack Overflow
NULL Define in c & c++ differs?! | Handmade Network
Why is there a NULL in the C language? - Stack Overflow
Videos
Hey, so when I was reading my gf's script for C classes, the tutor has written that
In some compilers there is no NULL but it can be easily replaced by a short macro
#define NULL 0
Does any compiler exist, which actually does not recognize NULL?
The C standard requires that NULL be defined in locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h, and wchar.h.
The C++ standard requires that NULL be defined in the c* header corresponding to each of those.
The C standard is very strict about the names a standard can define--each standard header must define precisely the names the standard requires that header to define. The only other names it can define are those that are reserved for the implementation, such as those starting with an underscore followed by another underscore or a capital letter.
The C++ standard is much more permissive in this respect--including any one standard header can have the same effect as including any or all other standard headers.
From a practical viewpoint, C++ implementations used to take quite a bit of advantage of this permissiveness--that is, including one standard header frequently defined the names from a number of other standard headers. More recent implementations tend to work more like the C standard requires, staying much closer to each header defining only the names required by to be defined by that header. They're still probably not as strict about it as the C standard requires, but much closer than they used to be (as a rule).
C++03 section 18.1.2 says that NULL is defined in cstddef.
On some implementations, iostream may include cstddef, so including iostream would also give you NULL.
Actually, you can use a literal 0 anyplace you would use NULL.
Section 6.3.2.3p3 of the C standard states:
An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
And section 7.19p3 states:
The macros are:
CopyNULLwhich expands to an implementation-defined null pointer constant
So 0 qualifies as a null pointer constant, as does (void *)0 and NULL. The use of NULL is preferred however as it makes it more evident to the reader that a null pointer is being used and not the integer value 0.
NULL is used to make it clear it is a pointer type.
Ideally, the C implementation would define NULL as ((void *) 0) or something equivalent, and programmers would always use NULL when they want a null pointer constant.
If this is done, then, when a programmer has, for example, an int *x and accidentally writes *x = NULL;, then the compiler can recognize that a mistake has been made, because the left side of = has type int, and the right side has type void *, and this is not a proper combination for assignment.
In contrast, if the programmer accidentally writes *x = 0; instead of x = 0;, then the compiler cannot recognize this mistake, because the left side has type int, and the right side has type int, and that is a valid combination.
Thus, when NULL is defined well and is used, mistakes are detected earlier.
In particular answer to your question โIs there a context in which just plain literal 0 would not work exactly the same?โ:
- In correct code,
NULLand0may be used interchangeably as null pointer constants. 0will function as an integer (non-pointer) constant, butNULLmight not, depending on how the C implementation defines it.- For the purpose of detecting errors,
NULLand0do not work exactly the same; usingNULLwith a good definition serves to help detect some mistakes that using0does not.
The C standard allows 0 to be used for null pointer constants for historic reasons. However, this is not beneficial except for allowing previously written code to compile in compilers using current C standards. New code should avoid using 0 as a null pointer constant.