Usage of C++ NULL vs 0

M

muktipada

Hello,

As a C++ developer which one we should use for pointer assignment,
NULL or 0.

typedef DummyC DummyClass*; // in some header file.

DummyC obj = NULL;

if (obj == NULL) {
// It gives an impression that obj is a pointer
}

OR

DummyC obj = 0;

if (obj == 0) {
// it gives an impression that obj is an integer, which is not true.
}

I understand NULL is a macro and defined to 0. But for readibility
purpose should
we use NULL for poiner. and 0 for integer.

Also since system provide NULL to be defined to some value(today it is
0) and if
tomorrow the defined value changes, then still our code will be
portable
if we use NULL. So I think instead of using hard coaded value 0, we
should
use NULL for pointer. It increases both for readbility and
portability. Any suggestion?

Regards,
-mukti
 
P

puzzlecracker

I believe you meant

     typedef DummyClass * DummyC;









Use 'NULL' because when 'nullptr' becomes part of the language, it would
be much easier to do a search-and-replace.




Don't strain your brain about the "system provide NULL to be defined"
thing.  The Standard says that NULL is a null pointer constant
expression.  Right now it is an expression that evaluates to 0 (it can
be, e.g. (123-123) ).  Whatever the "system provide" cannot be different
from that, really.

V

Isn't true that in C, NULL has a slightly different meaining -1?

If you code is still working with C components, that might cause issues
 
J

Joe Greer

Isn't true that in C, NULL has a slightly different meaining -1?

If you code is still working with C components, that might cause issues

I don't know what the latest standard says, but it at least used to be true
that in C NULL was ((void *)0) At least on some systems. This is illegal
in C++.

joe
 
M

Matthias Buelow

muktipada said:
As a C++ developer which one we should use for pointer assignment,
NULL or 0.

For assignment, I use 0 (in both C and C++) and usually !p for testing
for a null pointer. IMHO "NULL" is ugly and probably just a workaround
left over from the days when assigning 0 to pointers could have caused
type problems.
 
J

Juha Nieminen

muktipada said:
As a C++ developer which one we should use for pointer assignment,
NULL or 0.

Many C++ developers prefer 0 because it avoids the need to #include
whichever header NULL was defined in.

The only situation where using 0 as null pointer might cause ambiguity
problems is in overloading situations like this:

void foo(int i);
void foo(SomeType*);

int main()
{
foo(0); // ambiguous
}

In practice the int version of the function will be called (although
I'm not 100% sure what the standard says about this), which might not be
what the programmer wanted.

A properly-implemented NULL would avoid the ambiguity. Rather oddly,
though, the NULL macro in many compilers still cause ambiguity, and a
"foo(NULL);" will call the int version regardless (gcc at least issues a
warning, though).
 
B

Bo Persson

muktipada said:
Hello,

As a C++ developer which one we should use for pointer assignment,
NULL or 0.

typedef DummyC DummyClass*; // in some header file.

DummyC obj = NULL;

if (obj == NULL) {
// It gives an impression that obj is a pointer
}

OR

DummyC obj = 0;

if (obj == 0) {
// it gives an impression that obj is an integer, which is not true.
}

If so, perhaps the problem is that 'obj' isn't a very good name for a
variable?

Does

if (NumberOfElements == NULL)
{

}

also give the impression that NumberOfElements is a pointer? No.
I understand NULL is a macro and defined to 0. But for readibility
purpose should
we use NULL for poiner. and 0 for integer.

Maybe, maybe not.

Many C++ programmers tries to avoid macros, especially when they don't
do anything useful.


Bo Persson
 
J

Juha Nieminen

Victor said:
Here you go with that "ambiguity" claim again. What compilers are
those? Name at least one that in the code you provided reports any
ambiguity if you change 'foo(0)' to 'foo(NULL)'. At least *one*. I am
very curious.

gcc gives the following warning when NULL is used in this case:

warning: passing NULL to non-pointer argument 1 of 'void foo(int)'

I suppose that the idea behind the warning is "the C++ standard
requires me to call the int version of foo(), but since you are passing
NULL, it looks quite suspicious, and probably not what you intended".

(Note that gcc *always* gives this warning, even if no warning options
have been specified.)
 
F

Fraser Ross

It says in N2214:
// Partial specialization cases
template<typename T> class X { };
template<typename T> class X<T*> X { }; // case X<T*>
The second X there must be a mistake.

template<typename T> class X<T::*> X { }; // case X<T::*>
Same again there.

X<nullptr_t> x; // error, ambiguous; nullptr_t is both a pointer
// and pointer-to-member type, so it's undecidable which
// partial specialization to use

Is it possible to use explicit qualification to resolve this case and if
so what is the syntax? I think the answer is probably no and this is a
weak spot.

Fraser.
 
F

Fraser Ross

"Fraser Ross"
template<typename T> class X<T::*> X { }; // case X<T::*>

template<typename T, typename C> class X<T C::*> X { };

Thats a partial specialisation for X with a pointer to a data member of
C of type T. The paper doesn't make sense.

Fraser.
 
J

James Kanze

As a C++ developer which one we should use for pointer
assignment, NULL or 0.
typedef DummyC DummyClass*; // in some header file.

That won't compile. I think you mean:

typedef DummyClass* DummyC ;
DummyC obj = NULL;
if (obj == NULL) {
// It gives an impression that obj is a pointer
}

DummyC obj = 0;
if (obj == 0) {
// it gives an impression that obj is an integer, which is not true.
}
I understand NULL is a macro and defined to 0. But for
readibility purpose should we use NULL for poiner. and 0 for
integer.

That is a major unanswered question. Using NULL correctly
indicates intent, but some people object on the grounds that the
compiler doesn't understand that intent, e.g.:

void f( char const* ) ;
void f( int ) ;

f( NULL ) ; // Calls f( int )...

I use NULL, but I also don't overload when it makes a difference
which function will be called. (I'll give the functions
different names.) If you like all of your functions to have the
same name, with the semantics of the program depending on
overload resolution, then NULL is probably not a good idea.
Also since system provide NULL to be defined to some
value(today it is 0) and if tomorrow the defined value
changes, then still our code will be portable if we use NULL.

The standard requires the macro NULL to be defined as a null
pointer constant. Any null pointer constant you use, NULL, 0,
(1-1), '\0', etc. will work the same as far as the comiler is
concerned.
So I think instead of using hard coaded value 0, we should use
NULL for pointer. It increases both for readbility and
portability. Any suggestion?

It doesn't affect portability. I agree with regards to
readability, but opinions differ on the question, and I don't
think that there is a "right" answer. (Well, there is, sort of:
the next version of the standard will have a null_ptr, which
will work the way it should.)
 
J

James Kanze

[...]
Isn't true that in C, NULL has a slightly different meaining -1?

No. Both languages require NULL to be defined as a "null
pointer constant", and both require "null pointer constants" to
work in the same way. Standard C (but not traditional C) does
allow more liberty in what is considered a null pointer
constant, but that's not really relevant; if you compile your
C++ code as C++, and your C code as C, there won't be any
problems.
If you code is still working with C components, that might
cause issues

Such as?
 
J

James Kanze

For assignment, I use 0 (in both C and C++) and usually !p for
testing for a null pointer. IMHO "NULL" is ugly and probably
just a workaround left over from the days when assigning 0 to
pointers could have caused type problems.

I think you've got it backwards. C++ is a typed language, and
you should say what you mean. In particular, a conditional
should have type bool, rather than count on some obscure
implicit conversions. The use of 0 for a null pointer is a
hang-over from C, where the authors forgot to provide a proper
null pointer constant (probably because the language was
evolving from B, which didn't have a bool type---or any types,
for that matter). The next release of the C++ standard will
correct this oversight.
 
J

James Kanze

Many C++ developers prefer 0 because it avoids the need to
#include whichever header NULL was defined in.

Now that's the worse reason I've heard to date:). Many C++
developers prefer NULL, because at least with some compilers,
accidentally using it as an integral type will provoke a
warning.
The only situation where using 0 as null pointer might cause
ambiguity problems is in overloading situations like this:
void foo(int i);
void foo(SomeType*);
int main()
{
foo(0); // ambiguous

Totally unabiguous. It calls foo(int).

The problem here, of course (and the major argument against
NULL), is that f(NULL) is also unambiguous... and calls
foo(int). But as I said, good compilers (well, at least g++)
will warn in this case.
In practice the int version of the function will be called
(although I'm not 100% sure what the standard says about
this), which might not be what the programmer wanted.
A properly-implemented NULL would avoid the ambiguity. Rather
oddly, though, the NULL macro in many compilers still cause
ambiguity, and a "foo(NULL);" will call the int version
regardless (gcc at least issues a warning, though).

Nothing odd about it; it's what the standard requires (for
historical reasons). But as you say, g++ warns.

More bothersome are cases like:

template< typename T >
void f( T ) ;

where you don't know which instantiation you'll get with NULL
(although you know that T will be an integral type).
 
J

James Kanze

<bcd6ef13-9b2b-476c-915d-31ccae447...@q28g2000prh.googlegroups.com>,

[...]
Actually no, NULL does not fully accomodate all NULL'ness
(ugh) considerations in either C or C++.

But it comes a lot closer in C. (You're right to have
mentionned C, though, since it brings up the case which hasn't
been mentionned yet: var args. Where if the function is
expecting a pointer, neither NULL nor 0 work.)
 
F

Fraser Ross

Is anyone interested in this? This could be the partial specialisation
example:

template<typename T>
class X {};

template<typename T>
class X<T*> {}; //1

template<typename T, typename C>
class X<T C::*> {}; //2

X<nullptr_t> x;

When there is only 1 and not 2, does nullptr_t become the type for T?

When there is only 2 and not 1, does nullptr_t become the type for both
T and C?


Fraser.
 
M

Matthias Buelow

James said:
I think you've got it backwards. C++ is a typed language, and
you should say what you mean. In particular, a conditional
should have type bool, rather than count on some obscure
implicit conversions. The use of 0 for a null pointer is a
hang-over from C, where the authors forgot to provide a proper
null pointer constant (probably because the language was
evolving from B, which didn't have a bool type---or any types,
for that matter). The next release of the C++ standard will
correct this oversight.

I don't like verbosity and bureaucracy in programming languages. The
static typing in C++ is a means to an end and not something to worship
for its own sake. I think, checking if a pointer is "valid" in some
context is clearer conceptually than any technicalities in expressing
whether it has a value of a particular type. Too much useless detail
there (that's a frequent complaint I have with C++ but at least in a few
situations, one can do things better without the compiler barfing all
over the place, at least still. No doubt this will be "fixed" sometime,
too.)
 
M

Matthias Buelow

James said:
evolving from B, which didn't have a bool type---or any types,

Ah, just to stoke the fire a bit.. I don't like boolean types, either
:). I think C got it right in the first try.
 
J

James Kanze

I don't like verbosity and bureaucracy in programming languages. The
static typing in C++ is a means to an end and not something to worship
for its own sake. I think, checking if a pointer is "valid" in some
context is clearer conceptually than any technicalities in expressing
whether it has a value of a particular type.

But you can't check whether a pointer is valid; you just have to
know. (I agree that it would be nice if pointers had an
isValid() member function, but they don't.)
Too much useless detail there (that's a frequent complaint I
have with C++ but at least in a few situations, one can do
things better without the compiler barfing all over the place,
at least still. No doubt this will be "fixed" sometime, too.)

Well, it does require you do know what you're doing. I'd hardly
call that a disadvantage, however.
 
M

Matthias Buelow

James said:
But you can't check whether a pointer is valid; you just have to
know.

Yes.. what I mean is that in the language context, where a non-null
pointer is used to indicate an "valid" pointer:

if (p) vs. if (NULL != p).

I find the first form more meaningful and it hides the detail that the
pointer has the value NULL, a technicality which I'm not really
interested in here.
(I agree that it would be nice if pointers had an
isValid() member function, but they don't.)

if (p) vs. if (p.isValid()) ?

I think I prefer the first.
Well, it does require you do know what you're doing. I'd hardly
call that a disadvantage, however.

IMHO the disadvantage is that one can easily get bogged down in a level
of detail that distracts from the problem I actually want to solve.
Maybe it's just me but a significant time of my C++ programming is spent
fighting the compiler. However, YMMV. Maybe my mental model just doesn't
map well onto C++. Curiously, I don't really have these problems with C,
though, although it is a more primitive language (but it is honest, and
doesn't pretend to be high-level.)
 
B

Bo Persson

Matthias said:
Yes.. what I mean is that in the language context, where a non-null
pointer is used to indicate an "valid" pointer:

if (p) vs. if (NULL != p).

That's one of the cases to test for.
I find the first form more meaningful and it hides the detail that
the pointer has the value NULL, a technicality which I'm not really
interested in here.


if (p) vs. if (p.isValid()) ?

I think I prefer the first.

But it doesn't answer the question that the second one would (if it
was available):

T* p = new T();
delete p;

if (p.isValid())
{
// p still points to a valid object
}
IMHO the disadvantage is that one can easily get bogged down in a
level of detail that distracts from the problem I actually want to
solve. Maybe it's just me but a significant time of my C++
programming is spent fighting the compiler. However, YMMV. Maybe my
mental model just doesn't map well onto C++. Curiously, I don't
really have these problems with C, though, although it is a more
primitive language (but it is honest, and doesn't pretend to be
high-level.)

Having just a small hammer and a screwdriver makes it simpler to
master one's tools. A skilled craftsman ("knowing what he is doing"),
can be much more productive with a nail gun or a chain saw.


Bo Persson
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,261
Messages
2,571,040
Members
48,769
Latest member
Clifft

Latest Threads

Top