Is NULL always false?

2020-01-24 12:04发布

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 null pointers
13条回答
太酷不给撩
2楼-- · 2020-01-24 12:53

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

查看更多
你好瞎i
3楼-- · 2020-01-24 12:54

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.

查看更多
We Are One
4楼-- · 2020-01-24 12:56

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.

查看更多
在下西门庆
5楼-- · 2020-01-24 12:56

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.

查看更多
贼婆χ
6楼-- · 2020-01-24 13:00

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.
查看更多
神经病院院长
7楼-- · 2020-01-24 13:02

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

查看更多
登录 后发表回答