uintptr_t与指针相加是否满足交换律?等价性求证
关于指针与uintptr_t混合相加的结果一致性问题
我明白此类操作的实际应用场景很难找到,本问题纯出于理论好奇而提出。
现有代码:
char b[SOME_SIZE];
请问在实现定义了uintptr_t的前提下,表达式
((char *)5) + ((uintptr_t)b)
的结果是否必然与更常规的表达式
(b) + ((uintptr_t)5)
一致?若将包含偏移量的“指针”与包含地址的uintptr_t相加,结果是否符合预期——即与直接将偏移量加到地址上的结果相同?
结论与分析
两者结果并不必然一致,核心原因如下:
- 指针运算的标准规则限制:C标准规定,指针加法要求一个操作数是指针,另一个是可转换为
ptrdiff_t的整数类型。uintptr_t是无符号整数类型,虽然能存储指针数值,但标准未保证它与指针相加的行为等价于普通整数与指针的加法——尤其是当操作数顺序颠倒时,没有规则约束结果必须对称。 - 整数转指针的实现定义行为:
(char *)5这种将整数直接转换为指针的操作属于实现定义行为,部分平台甚至会视为未定义行为(比如不支持非对齐地址、地址空间不包含该数值的系统)。基于这种非标准指针的加法运算,结果完全依赖平台实现,无通用性保障。 - 指针与uintptr_t的映射不确定性:
uintptr_t仅保证能容纳指针的数值,但指针的二进制表示与uintptr_t数值的映射关系是实现定义的。例如分段地址空间的平台中,指针的存储逻辑和uintptr_t的线性数值可能不匹配,交换操作数后加法结果自然不同。
另外,常规写法b + ((uintptr_t)5)的行为相对更可靠(前提是5作为偏移量在数组b的有效访问范围内,否则仍可能触发未定义行为),因为它严格遵循指针加法的标准规则:数组退化为指针后,加上整数偏移量,操作逻辑符合C标准的规范。
内容的提问来源于stack exchange,提问作者CPlus
相关产品推荐
相关产品推荐

