我们可以减去 NULL 指针吗?

Can we subtract NULL pointers?

由于指针运算是在同一个数组中定义的,我怀疑我们是否可以从另一个 NULL 中减去 NULL。我担心以下实施:

//first and second can both either be from the same array 
//or be both NULL
prtdiff_t sub(void *first, void *second){
    //Do I really need this condition?
    if(!first && !second)
        return (ptrdiff_t) 0;

    return second - first;
}

注意:这个关于C的问题。如果你正在寻找C++问题,它是here (the answer is different!). There is also common question对于C和C++。

不,你不能这样做:两个指针之间的差异仅针对指向同一数组元素的指针或指向末尾元素的指针定义。 (为此目的,对象算作单个元素数组)。

(intptr_t)second - (intptr_t)first 是有效的。

不允许减去两个 NULL 指针。 C standard states 的第 6.5.6p9 节:

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. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the header. If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions P and Q point to, respectively, the i -th and j -th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t . Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1 and as -((P)-((Q)+1)) , and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object.

因为没有指针指向数组对象,所以行为未定义。

你也不能减去两个void *,因为void是一个不完整的类型,指针减法取决于知道指向对象的大小。您 可以 将每个指针转换为 intptr_t 并减去它们,但是这会给您指针之间的字节差异,而不是索引差异。

C++03 §5.7/7 说:

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没有这样的规定

简单的答案是NO, YOU CAN'T SUBTRACT A NULL FROM ANOTHER NULL.

我认为你误解了这个定义:

NULL is clearly defined as: An integer constant expression with the value 0, or such an expression cast to type void, is called a null pointer constant. So I used to think that we could subtract one 0 from another 0.

现在,至于现在让我们来看看 GOOGLE 对 NULL 的定义

Null means having no value; in other words null is zero, like if you put so little sugar in your coffee that it's practically null. Null also means invalid. From the Latin nullus, meaning "not any," poor, powerless null is not actually there at all.

很明显,它表示 null 没有值。想一想你正试图从无中减去无

现在让我们换句话说,null 为零(当且仅当定义值时)你可以肯定地减去它(但不是你可以做一些像 char *ab = NULL,char *aa= NULL 和然后像 ab-aa 这样执行减法仍然是非法的)

但是没有人能够真正预测 null 的值,因此,当您无法获得该值时,您将无法对其执行任何操作(如减法、加法等)。