c – 指针相等是否意味着整数相等?

对于int * a,int * b,是否== b暗示(intptr_t)a ==(intptr_t)b?我知道在现代X86 cpu上也是如此,但C标准或POSIX或任何其他标准是否能为此提供保证?

解决方法

C标准无法保证这一点. (这个答案没有说明POSIX或其他标准是否说明了intptr_t.)关于intptr_t的C标准(2011,草案N1570)说的是:

7.20.1.4 1 The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type,then converted back to pointer to void,and the result will compare equal to the original pointer: intptr_t

作为理论证明,一个反例是具有24位地址的系统,其中高8位未使用,但可用的整数类型是8位,16位和32位.在这种情况下,C实现可以使intptr_t成为32位整数,并且它可以通过将24位地址复制到32位整数并忽略高8位来将指针转换为intptr_t.这些比特可能会遗留在之前的任何东西上.当intptr_t值转换回指针时,编译器会丢弃高8位,从而产生原始地址.在这个系统中,当a == b被评估指针a和b时,编译器通过仅比较地址的24位来实现这一点.因此,如果a和b指向同一对象a == b将为真,但是(intptr_t)a ==(intptr_t)b可能因为忽略的高位而评估为假. (注意,严格来说,a和b应该指向void,或者在转换为intptr_t之前应该转换为指向void的指针.)

一个例子是使用一些基址和偏移寻址的系统.在该系统中,指针可能由指定某个基址的16位和指定偏移的16位组成.基数可能是64字节的倍数,因此由base和offset表示的实际地址是base•64 offset.在这个系统中,如果指针a有基数2和偏移量10,它表示与指针b相同的地址,基数为1,偏移量为74.比较指针时,编译器会为每个指针计算base•64 offset并比较结果,所以a == b的计算结果为true.但是,当转换为intptr_t时,编译器可能只是复制这些位,从而为(intptr_t)a生成131,082(2•65536 10),为(intptr_t)b生成65,610(1•65536 74).然后(intptr_t)a ==(intptr_t)b的计算结果为false.但是将intptr_t转换回指针类型的规则会使原始指针仍然成立,因为编译器只会再次复制这些位.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...