You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

整数转换而来的指针做相等比较:属未定义行为还是实现定义行为?

C语言指针相等比较的行为判定问题
#define POINTER_TO_SOMETHING ((int*)(0x80000000))
#define BAD_POINTER ((int*)(0x12345678))

int *p = some_condition ? POINTER_TO_SOMETHING + 42 : BAD_POINTER;
if (p == BAD_POINTER) { ... }

问题

上述代码是否存在未定义行为(UB),还是仅存在实现定义行为?

补充信息:该代码运行于负责管理页表等操作的内核模式下,0x80000000及后续4KB地址已在页表中注册,但这类硬件相关信息与C语言层面的行为判定无关。

已知涉及无效指针的关系比较(<、>、<=、>=)属于未定义行为,C标准相关条款如下:

6.5.8 Relational operators

shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression

When two pointers are compared, ...
In all other cases, the behavior is undefined. ...

但未找到针对相等比较(==)的相关限制要求。转换为uintptr_t类型可减少歧义,但这并非本次问题的关注点。


分析结论

1. 整数到指针的转换:实现定义行为

BAD_POINTER通过(int*)(0x12345678)将整数转换为指针,根据C标准6.3.2.3条款:

整数可以转换为任意指针类型。除前文规定的情况外,结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,也可能是陷阱表示。

这意味着:

  • 如果转换结果是陷阱表示,则任何使用该指针的操作(包括赋值给p、参与相等比较)都会触发未定义行为;
  • 如果转换结果不是陷阱表示,该指针的有效性由实现定义(此处它指向的是无效地址,不属于任何对象/函数的指针)。

2. 指针相等比较的行为

对于p == BAD_POINTER的比较,需分两种情况讨论:

  • 当p取值为BAD_POINTER时:两个指针是同一值,根据C标准6.5.9条款,比较结果必然为1,这是标准定义的行为;
  • 当p取值为POINTER_TO_SOMETHING + 42时:该指针是有效指针(指向已注册地址范围内的对象/数组元素),而BAD_POINTER是无效指针,二者不满足C标准6.5.9中规定的指针相等的四种情况(均非空指针、不指向同一对象/函数、不指向同一数组的末尾、也不属于相邻数组的首尾衔接),因此比较结果必然为0,这也是标准定义的行为。

总结

代码的行为取决于整数到指针转换的结果:

  • 如果转换结果是陷阱表示,存在未定义行为;
  • 如果转换结果不是陷阱表示,仅存在实现定义行为(转换本身的结果由实现决定,但后续的相等比较行为是标准定义的)。

内容的提问来源于stack exchange,提问作者Sylvain Hubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 17:32:53