Reputation: 14257
Is it safe to assume that NULL
always translates to false in C?
void *somePtr = NULL;
if (!somePtr) {
/* This will always be executed? */
}
Or should an explicit check against the value of NULL
be made?
Upvotes: 82
Views: 61853
Reputation: 425
NULL is just a preprocessor definition. It's in stdio.h. Typically, only an insane person would redefine it, but it's possible. An example:
#include <stdio.h>
#ifdef NULL
#undef NULL
#endif
#define NULL 1
void main()
{
if (NULL)
printf("NULL is true\n");
else
printf("NULL is false\n");
}
This code will print "NULL is true". Try it if you don't believe me. Your compiler might not even warn you that you're doing something weird.
Upvotes: 4
Reputation: 400
The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant;
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
Example Definition:
#define NULL ((void*)0)
if ( expression ) statement
if ( expression ) statement else statement
In both forms, the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal §6.8.4.1 Language 133 ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256 to 0. If the first substatement is reached via a label, the second substatement is not executed.
So yes if the compiler is compliant with ISO C99 you can assume that the statement below will always execute.
if (!NULL) { statement; }
Above quotations are from ISO/IEC 9899:1999 (C99). You can read it here.
Upvotes: 3
Reputation: 1614
According to me, it's not always safe to assume that. Since, depending on which headers have been included in a program, it can have been redefined. But according to the standard, the null pointer constant is guaranteed not to point to any real object and has a type void *
.
In our case, the declaration void *somePtr = NULL
could also be void *somePtr = 0
with 0
as null pointer.
“An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 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.” https://www.geeksforgeeks.org/few-bytes-on-null-pointer-in-c/
That simply means, evaluating *somePtr
at that specific point could result to false.
Another reference can be https://www.gnu.org/software/libc/manual/pdf/libc.pdf at page 944 A.3 about NULL Pointer Constant
Upvotes: 0
Reputation: 67476
Yes it:
C standard 6.3.2.3
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.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.
and 6.3.2.6
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
-
When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1
Upvotes: 3
Reputation: 31296
Yes, if(!p)
is valid and guaranteed to work.
An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 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.
https://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p3
This means that (void*)0
is a null pointer. It also means that if p
is a pointer, then p==0
is equivalent to p==(void*)0
.
It also means that if p
is a not a null pointer, then p==(void*)0
will evaluate to 0
.
So far, so good.
Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.
http://port70.net/~nsz/c/c11/n1570.html#6.3.2.3p4
Note that "Any two null pointers shall compare equal." This means that if p
is a null pointer, then p==0
will evaluate to true, because 0
will be promoted to (void*)0
which is a null pointer. It also mean that no non-null pointer can be equal to a null pointer.
Let's have a look at the negation operator.
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
http://port70.net/~nsz/c/c11/n1570.html#6.5.3.3p5
This tells us that !p
is the same as p==0
by definition, which is the same as p==(void*)0
as mentioned above.
And taking the fact that all null pointers are equal into consideration, this means that p==(void*)0
can only evaluate to true if p
is a null pointer and and only false if p
is not a null pointer.
So yes, if(!p)
is a perfectly safe way to check if p
is a null pointer or not.
Upvotes: 7
Reputation: 345
My copy of ISO/IEC 9899:TC3 (Committee Draft — Septermber 7, 2007) says:
6.3 Conversions
1 Several operators convert operand values from one type to another automatically.
6.3.2.3 Pointers
3 An integer constant expression with the value 0 [...] is called a null pointer constant. 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.
So far, ptr!=0
is true (1) for every non-null ptr
, but it's still open, how two null pointers compare.
6.5.9 Equality operators
5 [...] If one operand is a pointer and the other is a null pointer constant, the null pointer constant is converted to the type of the pointer.
6 Two pointers compare equal if and only if both are null pointers, both are [...]
Hence, ptr==0
is 1 (and ptr!=0
is 0), if and only if ptr
is a null pointer.
6.5.3.3 Unary arithmetic operators
5 The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
So the same holds for !ptr
.
6.8.4.1 The if statement
1 The controlling expression of an if statement shall have scalar type.
2 In both forms, the first substatement is executed if the expression compares unequal to 0.
Note, that a scalar type is an arithmetic type or a pointer type (see "6.2.5 Types", clause 21). Putting it together, we have:
if (ptr)
succeeds ⇔ ptr!=0
is 1 ⇔ ptr
is not a null pointer.if (!ptr)
succeeds ⇔ ptr==0
is 1 ⇔ ptr
is a null pointer.Upvotes: 14
Reputation: 7956
*NULL always targets to 0x00L. You can consider that false, but to be sure always do an explicit check.
Upvotes: -6
Reputation: 532445
Yes. NULL evaluates to false, since C considers any non-zero value true and any zero value false. NULL is essentially the zero
address and is treated as such in comparisons, and I believe would be promoted to an int for the boolean check. I would expect that your code is readable to anyone familiar with C although I would probably make the check explicit.
In C and C++ programming, two null pointers are guaranteed to compare equal; ANSI C guarantees that any null pointer will be equal to 0 in a comparison with an integer type; furthermore the macro NULL is defined as a null pointer constant, that is value 0 (either as an integer type or converted to a pointer to void), so a null pointer will compare equal to NULL.
Ref: http://en.wikipedia.org/wiki/Null_pointer#Null_pointer
Upvotes: 85
Reputation: 941217
The 'C' language dates from an era where (void*)0 could actually be a valid pointer. It is not that long ago, the 8080 and Z80 microprocessors had an interrupt vector at address 0. Faced with such architecture choices, it couldn't do anything but let a header file declare the value of NULL. There were some compilers out there, now long forgotten, where NULL was not equal to (void*)0 (0xffff was the next alternative), thus giving your if() statement undefined behavior.
C++ mercifully put an end to this, a null pointer is assignable from and testable against 0.
Upvotes: 22
Reputation: 1726
Yes (at least for any standards compliant C compiler!)
From the comp.lang.c FAQ:
Q: Is the abbreviated pointer comparison ``if(p)'' to test for non-null pointers valid? What if the internal representation for null pointers is nonzero?
A: It is always valid.
Upvotes: 17
Reputation: 10554
Yes, mostly.
First off, NULL is a typedef. I could royally screw you over by saying in a previously included header
#define NULL 1
This might not make a lot of sense, but since when has other people's code ever made sense? :)
Also, while it's probably syntactically safe, it's not semantically correct. NULL means "nothing", neither true or false or a boolean value or int or string. It means "a symbol for nothing". So testing for NULL is more like a philisophical issue: If a tree falls in the forest, and if(listener)
, does it make a sound?
Do everyone a favor and be clear about testing against NULL.
Upvotes: -2
Reputation: 95315
NULL
is defined as a constant pointer that is guaranteed to point to a useless/non-existent place in memory. Most implementations of NULL
are ((void *)0)
but it is not mandatory that this is so.
Upvotes: 0
Reputation: 9858
It's never safe to assume anything.
An explicit check is also more clear about what you're testing.
Upvotes: 19