6

由于指针算术是在同一个数组中定义的,我怀疑我们是否可以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

4 回答 4

10

不允许减去两个 NULL 指针。C 标准的第 6.5.6p9 节规定:

当两个指针相减时,都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素的下标之差。 结果的大小是实现定义的,其类型(有符号整数类型)是在标头中定义的 ptrdiff_t。如果结果在该类型的对象中不可表示,则行为未定义。换句话说,如果表达式 P 和 Q 分别指向数组对象的第 i 个和第 j 个元素,则表达式 (P)-(Q) 具有值 i-j,前提是该值适合ptrdiff_t 类型的对象。此外,如果表达式 P 指向数组对象的一个​​元素或数组对象的最后一个元素,而表达式 Q 指向同一数组对象的最后一个元素,则表达式 ((Q)+1) -(P) 与 ((Q)-(P))+1 和 -((P)-((Q)+1)) 具有相同的值,

因为两个指针都没有指向数组对象,所以行为是未定义的。

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

于 2019-04-18T14:03:00.533 回答
6

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

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

于 2019-04-18T14:02:43.247 回答
0

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

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

NULL 明确定义为:值为 0 的整型常量表达式,或这种类型转换为 void 的表达式,称为空指针常量。所以我曾经认为我们可以从另一个 0 中减去一个 0。

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

Null 表示没有价值;换句话说,null 是零,就像你在咖啡里放的糖太少以至于它实际上是 null 一样。Null 也意味着无效。来自拉丁语 nullus,意思是“没有”,可怜的、无能为力的 null 实际上根本不存在。

显然,它声明null没有value。想一想,当你试图从无中减去任何东西时

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

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

于 2019-04-18T14:26:58.617 回答
-2

C++03 §5.7/7 说:

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

但是C没有这样的规定。

于 2019-04-18T14:05:30.733 回答