NULL: Is it guaranteed to evaluate 'not true'

M

Mark A. Odell

Is NULL guaranteed to evaluate 'not true', e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}

Or must I check against NULL explicitly as in:

if (pFoo != NULL) ...

Thanks.
 
J

Joona I Palaste

Mark A. Odell said:
Is NULL guaranteed to evaluate 'not true', e.g. is it completely safe and
portable to write:
char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}

AFAIK it's indeed guaranteed to evaluate as "not true". Some C expert
will probably offer a more qualified opinion here.

--
/-- Joona Palaste ([email protected]) ---------------------------\
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste W++ B OP+ |
\----------------------------------------- Finland rules! ------------/
"This isn't right. This isn't even wrong."
- Wolfgang Pauli
 
M

Mike Wahler

Mark A. Odell said:
Is NULL guaranteed to evaluate 'not true',
Yes.

e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);

Portable, but not safe, since you didn't check
if malloc() succeeded or failed. If it failed,
then a dereference of 'pFoo' will give undefined
behavior.
if (pFoo)

This will be true if 'pFoo' is not == NULL.
{
/* use pFoo
*/
free(pFoo);
}

Or must I check against NULL explicitly as in:

if (pFoo != NULL) ...

No, you don't have to, but many coders prefer to
explicitly compare against NULL in the interest
of clarity.

-Mike
 
M

Mark A. Odell

Portable, but not safe, since you didn't check
if malloc() succeeded or failed.

I didn't? What's the following if (pFoo) for then? I did not dereference
pFoo until after the check if (pFoo).
If it failed,
then a dereference of 'pFoo' will give undefined
behavior.


This will be true if 'pFoo' is not == NULL.


No, you don't have to, but many coders prefer to
explicitly compare against NULL in the interest
of clarity.

I am certainly not one of them. I prefer C's "boolean" comparisons to
explicit values. Thanks for the reply.
 
M

Mike Wahler

Mark A. Odell said:
I didn't? What's the following if (pFoo) for then? I did not dereference
pFoo until after the check if (pFoo).

I'm still asleep it seems. :)
I am certainly not one of them.

Nor am I, except when constrained by coding standards
that require it.

<I prefer C's "boolean" comparisons to
explicit values.

As do I.
Thanks for the reply.

Thanks for the wake-up. :)

-Mike
 
N

Nick Austin

Is NULL guaranteed to evaluate 'not true', e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}

Correct and entirely safe.

if() expects an integer expression, which conventionally would be
the result yielded by a relational operator such as !=. This
result will either by zero (false) or non-zero (true).

If if() is supplied with a pointer expression this causes an
implicit pointer-to-integer conversion. In this case a
non-NULL pointer is converted to a non-zero integer. The NULL
pointer is converted to zero.

Nick.
 
A

Arthur J. O'Dwyer

Correct and entirely safe.

if() expects an integer expression,

Not true. 'if' expects to be controlled by an expression of
*scalar* type (basically, anything except an aggregate).
which conventionally would be
the result yielded by a relational operator such as !=. This
result will either by zero (false) or non-zero (true).

Sort of. 'if' compares its controlling expression to 0. If
it's not equal to 0, the body of the 'if' is executed. Otherwise,
the body of the 'if' is *not* executed. That's all.

For example,

if (foo)

is exactly equivalent to

if ((foo) != 0)

[you see now why aggregate types are not permitted in 'if'
conditions]. So, specifically,

if (pFoo)
if ((pFoo) != 0)

are equivalent expressions. And since 0 is in a pointer
context here, it's equivalent to a null pointer of type 'char *';
that is,

if (pFoo)
if ((pFoo) != NULL)
if ((pFoo) != (char*)0)

are also all equivalent. And of course they all do what you'd
expect.

If if() is supplied with a pointer expression this causes an
implicit pointer-to-integer conversion.

Nonsense. There is no "implicit pointer-to-integer conversion."
Ever. Under any circumstances. The language specifically
forbids it. The only implicit conversions are from pointers
to other pointer types, or from arrays to pointers, or between
different arithmetic types. That's it. (Unless I missed one.)

-Arthur
 
M

Mike Wahler

if() expects an integer expression, which conventionally would be
the result yielded by a relational operator such as !=. This
result will either by zero (false) or non-zero (true).

If if() is supplied with a pointer expression this causes an
implicit pointer-to-integer conversion.

This is news to me. Chapter and verse?

-Mike
 
M

Micah Cowan

Mike Wahler said:
This is news to me. Chapter and verse?

(To me too...)

Actually, the "implied conversion" would be integer-to-pointer,
since (according to the standard's definition), the scalar
expression will be compared with 0, requiring 0 to be converted
to NULL first.

(Naturally, by the as-if clause, no actual conversion is likely
in practice...)

-Micah
 
P

Peter Nilsson

Mark A. Odell said:
Is NULL guaranteed to evaluate 'not true',

Yes. The 'truth' of an arbitrary expressions X is determined by whether
"the expression compares unequal to 0." i.e. (X != 0).
e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}
Yes.


Or must I check against NULL explicitly as in:

if (pFoo != NULL) ...

No.
 
P

pete

Arthur said:
The only implicit conversions are from pointers
to other pointer types, or from arrays to pointers, or between
different arithmetic types.

Conversions from pointers to other pointer types require casts,
unless the conversion is to or from type pointer to void.
 
D

dis

Is NULL guaranteed to evaluate 'not true', e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}

Or must I check against NULL explicitly as in:

if (pFoo != NULL) ...

Both code fragments above are compliant. Note however that the argument to
the assert macro must be of type int under the C90 standard (and must be of
scalar type under the C99 standard):

#include <assert.h>
int main(void)
{
char *p = 0;
assert(p != 0); /* compliant under C90 and C99 */
assert(p); /* compliant under C99 only */
return 0;
}
 
M

Mark A. Odell

Note however that the argument to
the assert macro must be of type int under the C90 standard (and must be
of scalar type under the C99 standard):

#include <assert.h>
int main(void)
{
char *p = 0;
assert(p != 0); /* compliant under C90 and C99 */
assert(p); /* compliant under C99 only */
return 0;
}

This is a good point to make. Thank you. I hope that C99 compliant
compilers will soon dominate the C compiler market. However, Microsoft
seems not to be too interested judging by some previous posts.
 
D

Dan Pop

In said:
Is NULL guaranteed to evaluate 'not true', e.g. is it completely safe and
portable to write:

char *pFoo = malloc(1024);
if (pFoo)
{
/* use pFoo
*/
free(pFoo);
}

Or must I check against NULL explicitly as in:

if (pFoo != NULL) ...

Ever considered reading the FAQ?

5.3: Is the abbreviated pointer comparison "if(p)" to test for non-
null pointers valid?

Dan
 
M

Mark A. Odell

(e-mail address removed) (Dan Pop) wrote in
[snip]
Ever considered reading the FAQ?

Yes, I've done so on many occasion. I seem unable to retain the entire
body of knowledge it contains yet still believe to remember it in toto.
You're a bit late to the party on this one, you need to check news more
often.
 
D

Dave Thompson

And from function (designator) to pointer, and non-array lvalue to
(r)value, although the latter especially rather stretches the meaning
of the word. And in C99 pointer to _Bool, just for the heck of it.
Conversions from pointers to other pointer types require casts,
unless the conversion is to or from type pointer to void.

Or to add qualification.

- David.Thompson1 at worldnet.att.net
 
P

pete

Dave said:
And from function (designator) to pointer, and non-array lvalue to
(r)value, although the latter especially rather stretches the meaning
of the word. And in C99 pointer to _Bool, just for the heck of it.


Or to add qualification.

Thank you.
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) wrote in
[snip]
Ever considered reading the FAQ?

Yes, I've done so on many occasion. I seem unable to retain the entire
body of knowledge it contains yet still believe to remember it in toto.

Does this somehow mean that Mark A. Odell is exempt from the usual
requirement of checking the FAQ before asking questions?
You're a bit late to the party on this one, you need to check news more
often.

You're in dire need of a clue about how Usenet works!

Dan
 
M

Mark A. Odell

[snip]
if (pFoo != NULL) ...

Ever considered reading the FAQ?

Yes, I've done so on many occasion. I seem unable to retain the entire
body of knowledge it contains yet still believe to remember it in toto.

Does this somehow mean that Mark A. Odell is exempt from the usual
requirement of checking the FAQ before asking questions?

No, of course not. But I'm sure you know that I have read the FAQ despite
your implication, "Ever" to mean I have never read the FAQ.
You're in dire need of a clue about how Usenet works!

So you're telling me that your feed, typically quite responsive wasn't as
of late? I can except that Dan and yes I do know that usenet is not
immediate and has no such guarantee and that newservers may or may not
propagate messages in a time-regular manner.
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) wrote in
[snip]

if (pFoo != NULL) ...

Ever considered reading the FAQ?

Yes, I've done so on many occasion. I seem unable to retain the entire
body of knowledge it contains yet still believe to remember it in toto.

Does this somehow mean that Mark A. Odell is exempt from the usual
requirement of checking the FAQ before asking questions?

No, of course not. But I'm sure you know that I have read the FAQ despite
your implication, "Ever" to mean I have never read the FAQ.

OK, so you're sarcasm impaired. Unfortunately, there is no universally
accepted emoticon for sarcasm.
So you're telling me that your feed, typically quite responsive wasn't as
of late?

I'm telling you that it is downright foolish to make *any* assumptions
about someone's news feed. There are far too many things that can
happen at any type, regardless of its usual quality.

According to the c.l.c image provided my news server, no one else
had pointed you to the FAQ at the time I did it. Not being omniscient,
I had no idea about the contents of the posts that were still traveling
across the wire.

Dan
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top