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)说的是:
作为理论证明,一个反例是具有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转换回指针类型的规则会使原始指针仍然成立,因为编译器只会再次复制这些位. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |