我们可以减去NULL指针吗?

时间:2019-04-18 13:59:07

标签: c pointer-arithmetic null-pointer ptrdiff-t

由于指针算法是在同一数组中定义的,因此我不确定是否可以从另一个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;
}

4 个答案:

答案 0 :(得分:8)

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

  

当减去两个指针时,两个指针均应指向   同一数组对象,或在数组的最后一个元素之后   宾语;结果是下标的差异   两个数组元素。结果的大小为   实现定义的,其类型(有符号整数类型)为   标头中定义的ptrdiff_t。如果结果不是   在该类型的对象中可表示的行为是   未定义。换句话说,如果表达式P和Q指向   分别是   -th和j   如果数组对象的第n个元素适合于ptrdiff_t类型的对象,则表达式(P)-(Q)的值为ij。此外,   如果表达式P指向数组对象的元素,或者   在数组对象的最后一个元素之后,还有表达式Q   指向同一数组对象的最后一个元素,即表达式   ((Q)+1)-(P)与((Q)-(P))+ 1具有相同的值   -((P)-((Q)+1)),并且如果表达式P指向数组对象的最后一个元素的偶数,则该表达式的值为零,即使   尽管表达式(Q)+1并不指向数组的元素   对象。

由于两个指针均未指向数组对象,因此行为未定义。

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

答案 1 :(得分:6)

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

(intptr_t)second - (intptr_t)first仍然有效。

答案 2 :(得分:0)

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

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

  

NULL明确定义为:一个整数常量表达式,带有   值0或强制转换为void的表达式称为null   指针常量。所以我曾经以为我们可以从中减去1   另外0。

现在,就让我们采用GOOGLE对 NULL

的定义
  

空意味着没有没有价值;换句话说,null为零,例如   在您的咖啡中放很少的糖,以至于几乎没有糖。空值   也意味着无效。从拉丁文nullus,   意思是“没有任何”,可怜的,无能为力的null实际上根本不存在。

很明显,它指出没有没有值。在尝试一无所获一无所获时,请考虑一下。

现在换句话说,null为零(如果且仅当定义了值时),您可以确定地减去(但不能这样做,例如char * ab = NULL,char * aa = NULL,然后执行像ab-aa这样的减法仍然是非法的)

但是实际上没有人可以预测null的值,因此,当您无法获取该值时,您将无法对该值执行任何操作(例如减法,加法等)。

答案 3 :(得分:-2)

C ++ 03§5.7/ 7说:

  

如果将值0添加到指针值或从指针值中减去,则   结果比较等于原始指针值。如果两个指针   指向同一个对象,或者都指向同一对象的末尾   数组或两者均为空,并且两个指针相减,   结果比较等于转换为ptrdiff_t类型的值0。

但是对于C没有这样的规定。