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?

Joe
  • 8,251
  • 3
  • 18
  • 23
gigili
  • 195
  • 1
  • 13

6 Answers6

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.

John Hascall
  • 9,176
  • 6
  • 48
  • 72
wallyk
  • 56,922
  • 16
  • 83
  • 148
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 ) {
R Sahu
  • 204,454
  • 14
  • 159
  • 270
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.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
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.

August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
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.

Dennis
  • 3,683
  • 1
  • 21
  • 43
  • `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_. – too honest for this site Jan 11 '16 at 16:08
  • 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. – too honest for this site Jan 11 '16 at 16:10
  • If you wanted your own value to represent a `null`? – Dennis Jan 11 '16 at 16:14
  • What is a `null`? If you really want to obfuscate your code, `#define null nullptr`. This is the same as Pythons `NoneType`: There is exactly one object with that type: `None`. – too honest for this site Jan 11 '16 at 16:22
  • I just mean a `thing` called "null". You could I suppose do something like this `std::nullptr_t null;`. I've not tried it but it would be interesting to see what exactly that would do. Would `null == nullptr`? – Dennis Jan 11 '16 at 16:26
  • 1
    If `NULL` is not a macro defining a null pointer constant, it isn't a C++ compiler! – Martin Bonner supports Monica Jan 11 '16 at 16:36
  • You might mean a _null pointer_. `null` is just an arbitrary name, `NULL` is a macro required by the standard (C and C++). Please use standard terminology. FYI: http://port70.net/~nsz/c/c11/n1570.html – too honest for this site Jan 11 '16 at 16:46
  • @Dennis: Not sure about C++, but in C, _null pointers have to match `(void *)0`, even if they have different representation (e.g. encode the type). – too honest for this site Jan 11 '16 at 16:53
  • 2
    @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. – Deduplicator Jan 11 '16 at 17:00
  • @MartinBonner - Sorry, previously I has no parenthesis in the sentence, so the "most" applied to the value of 0. There is nothing to say another value could not be used. @Olaf - The snippet I had above was pure speculation based on your statement: "Not sure though where you would need that type, though". Just saying that you can in fact declare `nullptr_t` variables. – Dennis Jan 11 '16 at 17:03
  • @Deduplicator: The first part is the same as I stated. Not sure what you mean with "results in one". There is no requirement for a single _null pointer constant_ (the C standard at least clearly uses "**a** null pointer constant", not "**the** ..."). Note that a variable may be a _null pointer_, but - obviously - not a _null pointer constant_. – too honest for this site Jan 11 '16 at 17:08
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.
John Bode
  • 119,563
  • 19
  • 122
  • 198