0

I know a little bit about NULL, but when it comes to comparing I get confused.
For Example:

int* p; if(p == NULL){ //do stuff } if(p == 0){ //do stuff } 

In the first comparison "p" compares with what address?

Is it looking for the reference point of "p", and seeing if it is valid or not?

13
  • 21
    "I know that" followed by something completely absurd. Commented Jan 11, 2016 at 16:03
  • 1
    Please use either the C or C++ tag; they are separate languages. Commented Jan 11, 2016 at 16:07
  • 1
    Avoid writing multi-language source files. That is extremely hard work and it almost never has any advantage to writing single language source files. IOW: stick to one of C or C++. Commented Jan 11, 2016 at 16:07
  • 4
    "and see if it is valid or not" A pointer not being NULL does not mean, that the pointer is valid. Commented Jan 11, 2016 at 16:10
  • 6
    Why would this question attract so many down votes? Isn't down votes supposed to mean a badly phrased question? This question is as clear as it is and this is a question many new learners will ask. Commented Jan 11, 2016 at 16:10

6 Answers 6

3

In every modern implementation of C, NULL is zero, usually as a pointer value:

#define NULL (void *) 0 

So comparing, say, a character to NULL is likely to be invalid:

char ch = 'a'; if (ch == NULL) // probably "invalid comparison of pointer with scalar" 

As a pointer value, NULL chosen to point to invalid memory so that dereferencing it (on a suitable architecture) will cause a memory fault. Most virtual machines reserve lower memory just for this purpose and implemented by leaving low memory unmapped to physical memory. How much memory is unreserved? Could be a few kilobytes, but many implementations reserve a few megabytes.

Sign up to request clarification or add additional context in comments.

14 Comments

This answer is definitely wrong for C++ (can’t say for C).
@KonradRudolph: I am answering for C, but why do you say it is "definitely wrong for C++"?
Well because it is: the answer is incorrect for C++, and the question was tagged c++ (and c).
Ah, alright: in C++ NULL, is identical to the literal 0.
@KonradRudolph: Only code which is already broken. And silently? Sometimes, sometimes not.
|
3

NULL represents a value that is not used by any valid pointer. So, if a pointer is NULL, it points to no variable at all. In pointer contexts, the value zero means the same thing as NULL, however it is clearer to use NULL instead of zero. That's all you need to know about NULL.

5 Comments

It isn't irrelevant that NULL in a non-pointer-context might not be a pointer at all.
@Deduplicator Why would NULL appear in a non-pointer context?
Think of any variadic function, but C++ variadic templates. Or think of overloads in C++.
@Deduplicator Indeed, but with variadic functions all hope is gone when it comes to type safety.
How about C11 generic macros?
3

From the C99 Standard:

7.17 Common definitions <stddef.h>

3 The macros are

NULL 

which expands to an implementation-defined null pointer constant; ...

From the C++11 Standard:

18.2 Types

3 The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).194

Footnote 194:

194) Possible definitions include 0 and 0L, but not (void*)0.

Microsoft VS 2008 defines it as:

/* Define NULL pointer value */ #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif 

gcc/g++ 4.9.3 defines it as:

#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) #else /* C++ */ #define NULL 0 #endif /* C++ */ #endif /* G++ */ #endif /* NULL not defined and <stddef.h> or need NULL. */ 

I suspect other modern compilers define it similarly.

Given the above definitions of NULL, the line

if(p == NULL){ 

expands to:

if(p == ((void*)0) ){ 

in C.

It expands to

if(p == 0){ 

in C++.

In other C++ compilers, that line could expand to

if(p == 0L){ 

When using C++11, it is better to avoid NULL and start using nullptr instead.

if ( p == nullptr ) { 

1 Comment

Sometimes, your expansions are right... sometimes not.
3

Conceptually, NULL is a singular pointer-value pointing nowhere, and implicitly convertible to any pointer-type.
Practically, you unfortunately cannot depend on it behaving as a pointer value unless you use it in a pointer-only context.

Thus, use nullptr in C++11 and later respectively 0 cast to the right pointer-type, especially in contexts where an integral zero would not be converted to a pointer.

BTW: While on most modern systems a null pointer is really all-bits-zero, that's not required by the standard (there might be many bit-patterns representing null pointers, and none all-zero), and doesn't make any difference to how a null pointer constant is represented in source code.


In C++:

The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).

Which is defined as:

A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t.

Pre-C++11 the last option was obviously not available...
And post-C++11, because you do not know what it is, you should use nullptr directly.


In C:

The macros are NULL which expands to an implementation-defined null pointer constant; ...

Which is defined as:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

Comments

1

NULL in C++ compilers is just a macro defining a "null pointer constant" (generally of value 0). So there is no difference, apart from NULL being used to indicate an intent (which is important). For example you can create an int variable with the value NULL, which is not given any special treatment over the standard declaration (int a = 0;).

NULL is NOT "an empty space in memory". It is just a symbol that (generally) represents an absence of something (value, pointer etc...).

However using of NULL is now discouraged in C++ and the far superior nullptr should be used instead.

11 Comments

NULL does not define the integer value 0, but a null pointer constant. And there is one of the differences between C++ and C. And there is a a fundamental difference between a null pointer and a null pointer constant.
And in C++ the reserved name nullptr shall be used. std::nullptr_t is its type. Not sure though where you would need that type, though.
If you wanted your own value to represent a null?
If NULL is not a macro defining a null pointer constant, it isn't a C++ compiler!
@Olaf: Both C and C++ only require that all null pointers (after conversion) compare equal, and that a null pointer constant results in one, whatever bit-pattern it might have.
|
1

know that NULL is a empty space in memory

Not quite - NULL is a well-defined "nowhere" that doesn't correspond to any valid memory address.

In both C and C++, the NULL macro is defined to be a null pointer constant, which is a zero-valued integer expression. C++ also provides the nullptr literal, which also evaluates to the null pointer constant. When a null pointer constant appears in a pointer context, it will be converted to an implementation-defined null pointer value. A null pointer value may or may not be 0-valued, but it is guaranteed to compare unequal to any valid pointer value.

C 2011 online standard:

6.3.2.3 Pointers
...
3     An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 66) 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.
66)) The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.19

C++ 2014 online draft

2.13.7 Pointer literals [lex.nullptr]
    pointer-literal:
        nullptr

1     The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t. [Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10 and 4.11. — end note ]

4.10 Pointer conversions [conv.ptr]
1     A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a null pointer value. — end note ]
...
18.2 Types [support.types]
...
3     The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10).194
194) Possible definitions include 0 and 0L, but not (void*)0

To hammer some points home:

  1. The NULL macro, nullptr literal (C++ only), and null pointer constant are always 0-valued;
  2. The null pointer value does not have to be 0-valued;
  3. The null pointer value will never equal a valid memory address;
  4. It's the compiler's job to map the null pointer constant in your source code to the equivalent null pointer value in the generated machine code; as the programmer, you don't (generally) need to worry about the actual null pointer value on your implementation;
  5. Since a null pointer constant is always 0-valued, comparing a pointer value against 0 should be equivalent to comparing it against NULL or nullptr.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.