Is NULL always false?

CNullPointers

C Problem Overview


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?

C Solutions


Solution 1 - C

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

Solution 2 - C

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.

Solution 3 - C

It's never safe to assume anything.

An explicit check is also more clear about what you're testing.

Solution 4 - C

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.

Solution 5 - C

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.

Solution 6 - C

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.

Solution 7 - C

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.

Solution 8 - C


What is NULL?

> The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant;


What is the value of the 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)


Evaluating if(NULL)

> 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.

Solution 9 - C

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

Solution 10 - C

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.

Solution 11 - C

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

Solution 12 - C

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.

Solution 13 - C

*NULL always targets to 0x00L. You can consider that false, but to be sure always do an explicit check.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSydiusView Question on Stackoverflow
Solution 1 - CtvanfossonView Answer on Stackoverflow
Solution 2 - CHans PassantView Answer on Stackoverflow
Solution 3 - CakatakritosView Answer on Stackoverflow
Solution 4 - CCaptain SegfaultView Answer on Stackoverflow
Solution 5 - CRalphView Answer on Stackoverflow
Solution 6 - CkluttView Answer on Stackoverflow
Solution 7 - CbdowlingView Answer on Stackoverflow
Solution 8 - CMike SeedsView Answer on Stackoverflow
Solution 9 - C0___________View Answer on Stackoverflow
Solution 10 - CdreamlaxView Answer on Stackoverflow
Solution 11 - CGratien AsimbahweView Answer on Stackoverflow
Solution 12 - CMattView Answer on Stackoverflow
Solution 13 - CGabriel SosaView Answer on Stackoverflow