为什么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]
但是,将两个指针相加没有任何意义。所以这是不允许的。
- 请注意,对于
void *
指针以及不指向同一对象的各个部分的指针,这是未定义的行为。
为什么
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]
但是,将两个指针相加没有任何意义。所以这是不允许的。
- 请注意,对于
void *
指针以及不指向同一对象的各个部分的指针,这是未定义的行为。