严格地说,这是一种未定义的行为.
只有当指针指向有效数组对象(或单个对象)的成员,并且结果指向同一数组对象的成员时,执行指针算术,特别是将值添加到指针才有效.这在关于加法运算符的C standard条的第6.5.6p8节中有详细说明:
将整型表达式相加或相减时
在指针中,结果具有指针操作数的类型.如果
指针操作数指向数组对象的元素,数组
足够大,则结果指向从
元素的下标之间的差异
结果数组元素和原始数组元素等于整数表达式.
换句话说,如果表达式P指向
数组对象,表达式(P)+N(相当于N+(P))和(P)-N
(其中N的值为n)分别指向第i+n次和
I−数组对象的第n个元素,如果它们存在的话.此外,如果
表达式P指向数组对象的最后一个元素
表达式(P)+1指向数组对象的最后一个元素之后一个,
如果表达式Q指向数组的最后一个元素
对象,则表达式(Q)-1指向数组的最后一个元素
对象.如果结果指向最后一个元素之后的一个元素,则为If both the pointer operand and the result point to elements
of the same array object, or one past the last element of the array
object, the evaluation shall not produce an overflow; otherwise, the
behavior is undefined.
不能用作一元*的操作数.
被计算的运算符.
在这个表达式中:
((char *)5) + ((uintptr_t)b)
指针表达式(char *)5
没有指向有效的对象(除非您所在的系统明确允许使用"5"作为有效地址),因此对其执行算术运算是未定义的.
在地址只是一个32位或64位值的系统上,这将是probably,但不能保证这一点.一些编译器有pointer provenance的概念,它跟踪指针指向的对象,这样的构造可能会与执行优化时使用此概念的编译器冲突.
我见过一对指针a
和b
的例子,其中(uintptr_t)a == (uintptr_t)b
为真,而a == b
为假.