Is NULL always false?

前端 未结 13 1607
孤城傲影
孤城傲影 2020-11-27 04:44

Is it safe to assume that NULL always translates to false in C?

void *somePtr = NULL;

if (!somePtr) {
  /* This will always be executed? */
}
<         


        
相关标签:
13条回答
  • 2020-11-27 05:17

    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.

    0 讨论(0)
  • 2020-11-27 05:18

    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.
    0 讨论(0)
  • 2020-11-27 05:18

    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.

    0 讨论(0)
  • 2020-11-27 05:20

    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.

    0 讨论(0)
  • 2020-11-27 05:27

    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

    0 讨论(0)
  • 2020-11-27 05:27

    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

    0 讨论(0)
提交回复
热议问题