0 or NULL?

J

Johs32

If I have a pointer and initialize it to NULL does it have the same effect
if I initialize it to 0 instead, no matter what kind of pointer it is?
 
V

Vladimir S. Oka

Johs32 opined:
If I have a pointer and initialize it to NULL does it have the same
effect if I initialize it to 0 instead, no matter what kind of
pointer it is?

Yes, it is guaranteed by the Standard.

--
BR, Vladimir

schlattwhapper, n:
The window shade that allows itself to be pulled down,
hesitates for a second, then snaps up in your face.
-- Rich Hall, "Sniglets"
 
M

Mark McIntyre

If I have a pointer and initialize it to NULL does it have the same effect
if I initialize it to 0 instead, no matter what kind of pointer it is?

Yes, but its more user-friendly to use NULL, so that maintenance
programmers later on do not get confused.

Mark McIntyre
 
S

Skarmander

Johs32 said:
If I have a pointer and initialize it to NULL does it have the same effect
if I initialize it to 0 instead, no matter what kind of pointer it is?

Yes.

However, speaking of 0 versus NULL, there is a common kind of error that
surfaces when using 0 but not NULL on many systems: in order to pass a null
pointer to a variadic function (like printf()) you must explicitly cast the
null pointer constant to a pointer type. E.g.:

WRONG:
printf("%p", 0);

Here 0 is passed as an integer, not a pointer. This will fail on systems
where pointers and integers are not the same size and on systems where the
null pointer is not all-bits-zero.

STILL WRONG:
printf("%p", NULL);

This is still wrong because NULL can legally be defined as 0, triggering the
same problem. However, many systems define NULL as ((void*) 0), which
happens to work. Stress "happens to".

RIGHT:
printf("%p", (void*) 0);
printf("%p", (void*) NULL);

Variadic functions always have this problem because the compiler can't check
(or rather isn't required to check) the argument types. The same applies to
a call to a function which doesn't have a prototype in scope (just don't do
that).

For the full story (and a whole lot more), see chapter 5 of the FAQ:
http://www.c-faq.com/null/index.html.

S.
 
K

Keith Thompson

Skarmander said:
However, speaking of 0 versus NULL, there is a common kind of error
that surfaces when using 0 but not NULL on many systems: in order to
pass a null pointer to a variadic function (like printf()) you must
explicitly cast the null pointer constant to a pointer type. E.g.:

WRONG:
printf("%p", 0);

Here 0 is passed as an integer, not a pointer. This will fail on
systems where pointers and integers are not the same size and on
systems where the null pointer is not all-bits-zero.

STILL WRONG:
printf("%p", NULL);

This is still wrong because NULL can legally be defined as 0,
triggering the same problem. However, many systems define NULL as
((void*) 0), which happens to work. Stress "happens to".

Yes, but even if NULL is defined as ((void*)0), passing an unadorned
NULL to a variadic function is still wrong if the function expects a
pointer type other than void*. In most contexts, a void* value can be
used where an arbitrary object pointer type is needed (e.g., don't
cast the result of malloc()); the void* value will be implicitly
converted to the required type. But in a variadic function call, the
compiler doesn't know the required type, so it can't do the
conversion. (It happens to work if all pointer types have the same
representation).

printf() with "%p" is a special case because it happens to expect a
void*.
 
S

Skarmander

Keith said:
Yes, but even if NULL is defined as ((void*)0), passing an unadorned
NULL to a variadic function is still wrong if the function expects a
pointer type other than void*. In most contexts, a void* value can be
used where an arbitrary object pointer type is needed (e.g., don't
cast the result of malloc()); the void* value will be implicitly
converted to the required type. But in a variadic function call, the
compiler doesn't know the required type, so it can't do the
conversion. (It happens to work if all pointer types have the same
representation).
Yes, that's issue number three: aside from integers and pointers not needing
to be the same size and null pointers not needing to be represented by
all-bits-zero, pointers of different types need not have the same
representation (and null pointers are no exception). Variadic functions
happen to be the most obvious way to notice this.
printf() with "%p" is a special case because it happens to expect a
void*.
Yes, in retrospect my example is a little too specific to count as that. One
might be tempted to think that as long as you're passing void*, you're OK.
You're not.

S.
 
R

Richard Bos

Mark McIntyre said:
Yes, but its more user-friendly to use NULL, so that maintenance
programmers later on do not get confused.

Feh. If maintenance programmers do not know that 0 is a normal, valid
null pointer constant, they're to keep their fingers out of my code.

Richard
 
K

Keith Thompson

Feh. If maintenance programmers do not know that 0 is a normal, valid
null pointer constant, they're to keep their fingers out of my code.

x = 0;
y = NULL;

y is obviously a pointer. What about x?

Yes, you can look at the declaration to see what its type is, but any
hint you can give to maintenance programmers is helpful.
 
K

Keith Thompson

That's not an initialisation, though.

Ok, that's true. Nevertheless, I prefer to use NULL rather than 0 in
any pointer context, just as I use 0.0 for floating-point and '\0' for
characters.
 
R

Richard Bos

Keith Thompson said:
Ok, that's true. Nevertheless, I prefer to use NULL rather than 0 in
any pointer context, just as I use 0.0 for floating-point and '\0' for
characters.

Oh, I'm not saying that's a bad choice, not at all. I do think, though,
that a maintenance programmer who doesn't recognise other legal (and not
wilfully perverse) styles is not a good maintenance programmer.

Richard
 
J

jaysome

Richard said:
Oh, I'm not saying that's a bad choice, not at all. I do think, though,
that a maintenance programmer who doesn't recognise other legal (and not
wilfully perverse) styles is not a good maintenance programmer.

Right.

And I assume that the same "good maintenance programmer" who might add
some code would do something like this (minus the comments):

char *p = NULL; /* NULL or 0, doesn't matter, unless you want to be
consistent */
/* many lines later */
p = NULL; /* p is obviously a pointer */

instead of this:

char *p = 0; /* 0 or NULL, doesn't matter, unless you want to be
consistent */
/* many lines later */
p = 0; /* Okay, I see, p is an integer type */

That would sure make some other lives a lot easier.
 

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

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,280
Latest member
BGBBrock56

Latest Threads

Top