Printing null pointers with %p is undefined behavior?

前端 未结 3 986
無奈伤痛
無奈伤痛 2021-01-30 19:08

Is it undefined behavior to print null pointers with the %p conversion specifier?

#include 

int main(void) {
    void *p = NULL;

           


        
3条回答
  •  忘掉有多难
    2021-01-30 20:06

    The Short Answer

    Yes. Printing null pointers with the %p conversion specifier has undefined behavior. Having said that, I'm unaware of any existing conforming implementation that would misbehave.

    The answer applies to any of the C standards (C89/C99/C11).


    The Long Answer

    The %p conversion specifier expects an argument of type pointer to void, the conversion of the pointer to printable characters is implementation-defined. It doesn't state that a null pointer is expected.

    The introduction to the standard library functions states that null pointers as arguments to (standard library) functions are considered to be invalid values, unless it is explicitly stated otherwise.

    C99 / C11 §7.1.4 p1

    [...] If an argument to a function has an invalid value (such as [...] a null pointer, [...] the behavior is undefined.

    Examples for (standard library) functions that expect null pointers as valid arguments:

    • fflush() uses a null pointer for flushing "all streams" (that apply).
    • freopen() uses a null pointer for indicating the file "currently associated" with the stream.
    • snprintf() allows to pass a null pointer when 'n' is zero.
    • realloc() uses a null pointer for allocating a new object.
    • free() allows to pass a null pointer.
    • strtok() uses a null pointer for subsequent calls.

    If we take the case for snprintf(), it makes sense to allow passing a null pointer when 'n' is zero, but this is not the case for other (standard library) functions that allow a similar zero 'n'. For example: memcpy(), memmove(), strncpy(), memset(), memcmp().

    It is not only specified in the introduction to the standard library, but also once again in the introduction to these functions:

    C99 §7.21.1 p2 / C11 §7.24.1 p2

    Where an argument declared as size_t n specifies the length of the array for a function, n can have the value zero on a call to that function. Unless explicitly stated otherwise in the description of a particular function in this subclause, pointer arguments on such a call shall still have valid values as described in 7.1.4.


    Is it intentional?

    I don't know whether the UB of %p with a null pointer is in fact intentional, but since the standard explicitly states that null pointers are considered invalid values as arguments to standard library functions, and then it goes and explicitly specifies the cases where a null pointer is a valid argument (snprintf, free, etc), and then it goes and once again repeats the requirement for the arguments to be valid even in zero 'n' cases (memcpy, memmove, memset), then I think it's reasonable to assume that the C standards committee isn't too concerned with having such things undefined.

提交回复
热议问题