Is it safe to assume that NULL
always translates to false in C?
void *somePtr = NULL;
if (!somePtr) {
/* This will always be executed? */
}
<
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.
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.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.
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
#define NULL 1
#endif
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.
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
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