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

C语言中不同类型的两个独立变量的地址是否可能相等?

C语言中不同类型的两个独立变量的地址是否可能相等?

首先直接给你结论:对于代码里定义的两个独立变量x和y,你写的三个断言全部都会永远成立,C标准完全保证这一点。下面逐一解释原因,以及你关心的那些假设场景为什么不可能出现。

核心问题的解答

1. void*和char*的指针比较

C标准的对象模型规定:每个独立的对象(变量属于对象的一种)都拥有唯一的存储位置。当你把指向不同对象的指针转换为void*后进行比较,结果一定是不相等的——因为void*是通用指针类型,它的比较语义就是直接对比对象的存储位置唯一性。

同样,char*的比较和void*语义完全一致:char*允许用来访问任何对象的原始字节,指向不同对象的char*指针,必然指向不同的存储位置,所以比较结果一定不等。

所以这两个断言:

assert((void*)(&x) != (void*)(&y)); // 必然通过
assert((char*)(&x) != (char*)(&y)); // 必然通过

是绝对安全的,不会有任何符合C标准的编译器让它们失败。

2. 指针转换为整数类型后的比较

对于(uint64_t)(&x) != (uint64_t)(&y)这个断言,只要你的系统中uint64_t是适合存储指针的类型(比如系统的uintptr_t就是uint64_t,或者sizeof(uint64_t) >= sizeof(void*)、指针可以无损转换为该整数),那么这个断言也一定会成立。

C标准规定:如果一个指针转换为整数类型,再转换回原指针类型,必须能精确指向原来的对象。如果两个不同对象的指针转成整数后相等,那么把这个整数转回去就会指向同一个对象,这就违反了“不同对象有唯一存储位置”的规则。因此,符合标准的编译器必须保证,不同对象的指针转成合适的整数类型后,值一定不同。

关于你假设的特殊硬件场景

你担心的“不同类型变量存在不同内存区域(比如GPU内存和CPU内存)但地址数值相同”的情况,C标准明确禁止这种情况出现在C语言的抽象模型中。

不管底层硬件怎么实现,编译器必须从C语言的视角隐藏这些细节——也就是说,在C代码的逻辑里,每个对象的地址是唯一的标识,和它的类型无关。不存在“同一地址但类型不同就指向不同内存区域”的情况,因为这会彻底破坏C的对象模型和指针的语义。

举个例子:如果真的有这种硬件,编译器必须为不同类型的变量分配不同的、可以区分的地址(比如给GPU内存的变量地址加上一个偏移量),保证在C代码里,不同对象的地址比较结果是正确的。

结合你找到的标准条款和资料

你提到的C23标准6.5.9条款:“如果两个指向对象类型的指针都指向同一个对象,或者都指向同一个数组对象的最后一个元素之后的位置,则它们比较相等”。其实它的逆命题也是成立的——如果两个void*指针比较相等,那么它们一定指向同一个对象(或者同一数组的尾后位置)。所以反过来,指向不同对象的void*指针一定不相等。

至于你看到的C里的备注,C和C的对象模型有差异。C++允许一些更复杂的对象模型场景,但C语言的对象模型更简单直接,严格保证每个独立对象的存储位置唯一性,不存在“同地址不同对象”的合法情况。

总结

所有你列出的断言,在符合C标准的环境下都会通过。C标准从根本上保证了不同独立对象的地址(无论是作为通用指针、字符指针还是合适的整数类型)都是唯一且可区分的。


备注:内容来源于stack exchange,提问作者Adam Sho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 09:05:27