为什么void指针可以减而不能加?

Why can void pointers be subtracted but not added?

为什么

printf("%ld\n", (void *)0 - (void *)0);

编译,但是

printf("%ld\n", (void *)0 + (void *)0);

没有?

对于初学者这个表达式

(void *)0 - (void *)0

具有未定义的行为,因为根据 C 标准(6.5.6 加法运算符)

3 For subtraction, one of the following shall hold:

— both operands are pointers to qualified or unqualified versions of compatible complete object types;

类型 void 是一个不完整的类型。

你可以这样写

(char *)0 - (char *)0

一些向后兼容的编译器有他们的语言扩展,允许对类型 cv void *.

的指针进行这样的操作

至于运算符+那么它只是没有为指针定义。对于应用于指针的此运算符,应满足

2 For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type.

对指针应用运算符 + 没有任何意义。

找出两个指针之间的差异很有用。这给出了一个整数 (a ptrdiff_t).[1]

给指针加一个差很有用,所以我们可以给指针加一个整数(反之亦然)。 ptrdiff = p2 - p1的逆运算为p2 = p1 + ptrdiff.[1]

但是,将两个指针相加没有任何意义。所以这是不允许的。


  1. 请注意,对于 void * 指针以及不指向同一对象的各个部分的指针,这是未定义的行为。