Is the behavior of subtracting two NULL pointers defined?

前端 未结 4 1024
死守一世寂寞
死守一世寂寞 2020-12-01 10:07

Is the difference of two non-void pointer variables defined (per C99 and/or C++98) if they are both NULL valued?

For instance, say I have a buffer struc

4条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-01 10:37

    In C99, it's technically undefined behavior. C99 §6.5.6 says:

    7) For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

    [...]

    9) When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. [...]

    And §6.3.2.3/3 says:

    An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.55) 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 since a null pointer is unequal to any object, it violates the preconditions of 6.5.6/9, so it's undefined behavior. But in practicality, I'd be willing to bet that pretty much every compiler will return a result of 0 without any ill side effects.

    In C89, it's also undefined behavior, though the wording of the standard is slightly different.

    C++03, on the other hand, does have defined behavior in this instance. The standard makes a special exception for subtracting two null pointers. C++03 §5.7/7 says:

    If the value 0 is added to or subtracted from a pointer value, the result compares equal to the original pointer value. If two pointers point to the same object or both point one past the end of the same array or both are null, and the two pointers are subtracted, the result compares equal to the value 0 converted to the type ptrdiff_t.

    C++11 (as well as the latest draft of C++14, n3690) have identical wording to C++03, with just the minor change of std::ptrdiff_t in place of ptrdiff_t.

提交回复
热议问题