Is a pointer pointing to 0x0000 the same as a pointer set to NULL? If NULL value is defined in the C language, then what location does it physically translate to? Is it the same as 0x0000. Where can I find more details about these concepts?
A point that most of the answers here are not addressing, at least not explicitly, is that a null pointer is a value that exists during execution, and a null pointer constant is a syntactic construct that exists in C source code.
A null pointer constant, as Karlson's answer correctly states, is either an integer constant expression with the value 0 (a simple
0 is the most common example), or such an expression cast to
void* (such as
NULL is a macro, defined in
<stddef.h> and several other standard headers, that expands to an implementation-defined null pointer constant. The expansion is typically either
((void*)0) (the outer parentheses are needed to satisfy other language rules).
So a literal
0, when used in a context that requires an expression of pointer type, always evaluates to a
null pointer, i.e., a unique pointer value that points to no object. That does not imply anything about the representation of a null pointer. Null pointers are very commonly represented as all-bits-zero, but they can be represented as anything. But even if a null pointer is represented as
(void*)0 is still a null pointer constant.
This implies, among other things, that
calloc(), which can set a region of memory to all-bits-zero, will not necessarily set any pointers in that region to null pointers. They're likely to do so on most implementations, but the language doesn't guarantee it.
I don't know why this question isn't considered a duplicate of this one, or how it's topical here.
Every platform out there is free to define NULL as it pleases.
According to the C Standard, if you assign zero to a pointer it will be converted to a NULL value (for that platform.) However, if you take a NULL pointer and cast it to int, there are no guarantees that you will get zero on every platform out there. The fact however is that on most platforms it will be zero.
Information about that stuff you can find in The C Language Specification. You can find them here.
It is defined in the C language because there is no one unvarying machine address that it equates to. If it did, we wouldn't need an abstraction from it! Even though on most platforms, NULL might eventually be implemented as 0 of some type or other, it's simply wrong to assume that this is universally so, if you care about portability at all.
According to C Standard Document section
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) 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.
So far I have not seen a compiler that has broken away from this.
On any MacOS or iOS device with a 64 bit processor, there is no memory location 0. Never has been, never will be. So when you ask "does it point to memory location 0", that doesn't make sense.
A null pointer has a representation as bits in memory. That representation can be anything depending on the compiler. All that is guaranteed is that assigning a null pointer to a pointer variable creates a null pointer, and that comparing two null pointers produces the result that they are equal. Comparing them with memcmp is not guaranteed to give the same bits.
There is a special rule that using a "null pointer constant" where a pointer is needed will produce a null pointer. For example: "char* p = 0;" stores a null pointer. "char* p = 1;" doesn't compile. "char* p = (int) 0;" doesn't compile because (int) 0 is not a null pointer constant. "char* p = (void*) 0;" stores a null pointer because (void*)0 is a null pointer constant. "char* p = (char*)0;" assigns 0 cast to char*, which isn't necessarily a null pointer.
The C standard says
The macros are
which expands to an implementation-defined null pointer constant;
and it also says
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.
So what does that actually all mean? Basically the C standard defines three things:
There exists a macro named
NULLwhich expands to a null pointer value (what value that actually is, is not defined, it's explicitly said to be implementation dependent)
Casting the integer
0to a pointer results in a null pointer (yet it does not require that the null pointer has
0as a value)
No pointer to any object or function can compare equal to a null pointer
NULL can have any value, as long as no valid object or function pointer can ever have this value and as long as the compiler generates exactly that value if the integer 0 is casted to a pointer. Whether you use
(void *)0 is irrelevant according to then standard, both result in a null pointer, thus
NULL is usually simply defined as
You just must not assume that a null pointer has
0 as a pointer value or points to
0x0 as that is nowhere defined. That is the case for all current implementations widely in use but it would not violate the standard if it wasn't.