14

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?

15

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 (void*)0).

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 0 or ((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 0xDEADBEEF, 0 or (void*)0 is still a null pointer constant.

This answer to the question on stackoverflow covers this well.

This implies, among other things, that memset() or 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.

| improve this answer | |
  • 1
    One of my peeves with the design and evolution of C is that the digit zero has continued to be used as a non-deprecated representation of a null pointer. Back in the earliest days of the language (e.g. before the advent of things like function prototypes), pointers and integers were sufficiently interchangeable that using "0" for a null pointer was simple and it would "just work". Once it became necessary to distinguish between the integer quantity zero and a null pointer, however, the "0" representation should have been deprecated in favor of a keyword or operator sequence. – supercat Jul 13 '12 at 16:29
  • Does this mean that the NULL pointer may actually point to some location when it is assigned NULL depending on the platform? The null pointer constant maybe a syntactic construct but what exactly happens when the code runs? Lets suppose this syntactic construct has been compiled on the GNU/Linux platform. What is the pointer value when we assign NULL to it? How does this address differ from any other address? – Arpith Aug 6 '12 at 13:16
  • 1
    @Arpith: Assigning NULL, or any null pointer constant, to a pointer object sets that object's value to a null pointer. On the machine level, it may well point to some valid chunk of memory. Dereferencing a null pointer has undefined behavior; accessing a chunk of memory at address 0x0000000 is valid behavior, as is literally anything else. That address differs from any other address by (a) comparing equal to NULL, and (b) comparing unequal to any pointer to a C object. A null pointer is an arbitrary pointer value used to indicate that it doesn't point to anything. – Keith Thompson Aug 6 '12 at 19:01
  • 1
    On the machine level, it may point to some valid chunk of memory, but in most C environments it will point to invalid memory so that any attempt to use the pointer will result in a hardware trap/fault/exception. It's usually only on the very simplest hardware platforms---ones with no support for memory management---where a NULL pointer points to a valid memory location. – Solomon Slow Jun 21 '16 at 17:07
7

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.

| improve this answer | |
  • 2
    If they choose to break away from the standard they are free to redefine NULL pointer constant. As far as I know there are no compilers out there that do that. – Karlson Jan 4 '12 at 15:07
  • Is there any compiler out there that doesn't implement NULL as 0? And is NULL guaranteed to evaluate to false? – ugoren Jan 4 '12 at 22:27
  • NULL is guaranteed to evaluate to false by the standard. I do not know if there is any compiler (platform, actually) that does not implement NULL as 0, and I seriously doubt it, but the standard does not prohibit it, so who knows. – Mike Nakis Jan 4 '12 at 22:52
  • There is confusion between representation of the abstract "null pointer constant" (as mentioned in the spec) in memory, which may be as the platform maker pleases and the definition of NULL macro, which has to expand to 0 in C++ and either 0 or (void *)0 in C, because that is the real "null pointer constant". – Jan Hudec Jan 5 '12 at 10:13
  • While NULL can be in theory be defined as anything, there is however a guarantee by the standard that an int constant with the value 0 typecasted to a pointer will result in a null pointer (ISO 9899:1999 6.3.2.3/3). The NULL macro of stddef.h must be a null pointer (7.17/3), so it would be very burdensome for the compiler not to implement NULL as either 0 or (void*)0. – user29079 Jan 9 '12 at 14:00
1

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.

| improve this answer | |
0

According to C Standard Document section 6.3.2.3:

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.

| improve this answer | |
  • @PéterTörök You're right it's a tyop. :) – Karlson Jan 4 '12 at 15:25
  • 1
    Yes, but notice that it does not say anything about the pointer actually having numeric value of 0. It may not, though on most platforms it does. – Jan Hudec Jan 5 '12 at 10:08
0

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.

| improve this answer | |
0

The C standard says

The macros are

NULL

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:

  1. There exists a macro named NULL which expands to a null pointer value (what value that actually is, is not defined, it's explicitly said to be implementation dependent)

  2. Casting the integer 0 to a pointer results in a null pointer (yet it does not require that the null pointer has 0 as a value)

  3. No pointer to any object or function can compare equal to a null pointer

In theory 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 NULL or (void *)0 is irrelevant according to then standard, both result in a null pointer, thus NULL is usually simply defined as (void *)0.

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.

| improve this answer | |
  • "[...] if the integer 0 is casted to a pointer." no. if a literal 0 is cast to a pointer or used in a pointer context. Casting an integer 0 to a pointer might not result in a null pointer. – Deduplicator May 10 at 22:30
  • @Deduplicator Sorry but the C standard disagrees and I even quoted this part. The 1st sentence of the 2nd quote says exactly that. An integer constant expression with the value 0 - just 0 is an integer constant expression with the value 0 and casted to a pointer results into a null pointer. Why do you argue against something that is literal found in the standard? – Mecki May 11 at 8:36
  • "integer constant expression" is fundamentally different from "integer" – Deduplicator May 11 at 11:32
  • @Deduplicator An integer constant expression is any source code expression with constant result and of type integer. The literal integer 0 is of type integer and it is constant, so it is an integer constant expression. And the integer 0 is casted to a pointer. means (void *)0 just as an English sentence. – Mecki May 11 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.