I
Ioannis Vranos
Hi, in a discussion I am having with a programmer, we have a dispute if it is a good idea to use the macro
NULL instead of 0 for denoting a null pointer value.
I think 0 should be preferred and NULL should be avoided, but the other programmer says that using the macro
NULL in C++ is better, because it is easier to distinguish it.
Some of my arguments:
1. C++ standard mentions:
"A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
zero. 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 pointer to object or pointer to function type. 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)".
C standard mentions (from K&R2, page 198, ?6.6):
"An integral constant expression with value 0, or such an expression cast to type void *, may be converted, by
a cast, by assignment, or by comparison, to a pointer of any type. This produces a null pointer that is equal
to another null pointer of the same type, but unequal to any pointer to a function or object".
Also TC++PL3 mentions:
"5.1.1 Zero
Zero (0) is an int. Because of standard conversions (C.6.2.3), 0 can be used as a constant of any integral
(4.1.1), floating-point, pointer, or pointer-to-member type. The type of zero will be determined by context.
Zero will typically (but not necessarily) be represented by the bit pattern all-zeros of the appropriate size.
No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating that a
pointer doesn't refer to an object.
In C, it has been popular to define a macro NULL to represent the zero pointer. Because of C++'s tighter type
checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you
must define NULL, use
const int NULL= 0;
The const qualifier (5.4) prevents accidental redefinition of NULL and ensures that NULL can be used where a
constant is required".
So in C++, the "natural" value denoting a null pointer is the integral value 0, while in C, the "natural"
value denoting a null pointer is the value that *results* from the conversion of the integral value 0 to the
type of the pointer.
2. The C++ standard says about the macro NULL:
" The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10)
*180.
*180 Possible definitions include 0 and 0L, but not (void*)0".
I think this implies that an implementation may define macro NULL with an implemetation-defined way, for
example a keyword:
#define NULL _somekeyword
3. Since in C NULL is *usually* defined as a pointer type (e.g. #define NULL ((void *)0) ), and in C++ NULL is
*usually* defined with the integral value 0, a programmer that knows C may easily think that NULL is of
pointer type, and be easily confused by the code:
#include <iostream>
#include <cstddef>
void f(void *) { std::cout<< "f(void *) was called.\n"; }
void f(int) { std::cout<< "f(int) was called.\n"; }
void f(long) { std::cout<< "f(long) was called.\n"; }
int main()
{
f(NULL);
}
which in my system produces:
john@john-laptop:~/Projects/anjuta/cpp/src$ g++ -ansi -pedantic-errors -Wall main.cc -o foobar
john@john-laptop:~/Projects/anjuta/cpp/src$ ./foobar
==> f(long) was called.
john@john-laptop:~/Projects/anjuta/cpp/src$
So I think using NULL is a bad practice n C++.
The other programmer considers using NULL in C++ a good practice, because:
1. Using NULL denotes a pointer, while 0 has more uses, and when you see NULL you easily know that you are
dealing with a pointer.
2. NULL is easier to search and find in the source code.
3. NULL is the definition of a constant, and it can easily be modified, so in upcoming C++0x can be easily
defined as #define NULL nullptr.
Also the mentality of C++0x, is more towards the way of the old NULL, rather than 0.
So, using NULL is NOT a bad style.
So, who is right?
Thanks,
--
Ioannis A. Vranos
C95 / C++03 Developer
http://www.cpp-software.net
NULL instead of 0 for denoting a null pointer value.
I think 0 should be preferred and NULL should be avoided, but the other programmer says that using the macro
NULL in C++ is better, because it is easier to distinguish it.
Some of my arguments:
1. C++ standard mentions:
"A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to
zero. 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 pointer to object or pointer to function type. 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)".
C standard mentions (from K&R2, page 198, ?6.6):
"An integral constant expression with value 0, or such an expression cast to type void *, may be converted, by
a cast, by assignment, or by comparison, to a pointer of any type. This produces a null pointer that is equal
to another null pointer of the same type, but unequal to any pointer to a function or object".
Also TC++PL3 mentions:
"5.1.1 Zero
Zero (0) is an int. Because of standard conversions (C.6.2.3), 0 can be used as a constant of any integral
(4.1.1), floating-point, pointer, or pointer-to-member type. The type of zero will be determined by context.
Zero will typically (but not necessarily) be represented by the bit pattern all-zeros of the appropriate size.
No object is allocated with the address 0. Consequently, 0 acts as a pointer literal, indicating that a
pointer doesn't refer to an object.
In C, it has been popular to define a macro NULL to represent the zero pointer. Because of C++'s tighter type
checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you
must define NULL, use
const int NULL= 0;
The const qualifier (5.4) prevents accidental redefinition of NULL and ensures that NULL can be used where a
constant is required".
So in C++, the "natural" value denoting a null pointer is the integral value 0, while in C, the "natural"
value denoting a null pointer is the value that *results* from the conversion of the integral value 0 to the
type of the pointer.
2. The C++ standard says about the macro NULL:
" The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10)
*180.
*180 Possible definitions include 0 and 0L, but not (void*)0".
I think this implies that an implementation may define macro NULL with an implemetation-defined way, for
example a keyword:
#define NULL _somekeyword
3. Since in C NULL is *usually* defined as a pointer type (e.g. #define NULL ((void *)0) ), and in C++ NULL is
*usually* defined with the integral value 0, a programmer that knows C may easily think that NULL is of
pointer type, and be easily confused by the code:
#include <iostream>
#include <cstddef>
void f(void *) { std::cout<< "f(void *) was called.\n"; }
void f(int) { std::cout<< "f(int) was called.\n"; }
void f(long) { std::cout<< "f(long) was called.\n"; }
int main()
{
f(NULL);
}
which in my system produces:
john@john-laptop:~/Projects/anjuta/cpp/src$ g++ -ansi -pedantic-errors -Wall main.cc -o foobar
john@john-laptop:~/Projects/anjuta/cpp/src$ ./foobar
==> f(long) was called.
john@john-laptop:~/Projects/anjuta/cpp/src$
So I think using NULL is a bad practice n C++.
The other programmer considers using NULL in C++ a good practice, because:
1. Using NULL denotes a pointer, while 0 has more uses, and when you see NULL you easily know that you are
dealing with a pointer.
2. NULL is easier to search and find in the source code.
3. NULL is the definition of a constant, and it can easily be modified, so in upcoming C++0x can be easily
defined as #define NULL nullptr.
Also the mentality of C++0x, is more towards the way of the old NULL, rather than 0.
So, using NULL is NOT a bad style.
So, who is right?
Thanks,
--
Ioannis A. Vranos
C95 / C++03 Developer
http://www.cpp-software.net