鉴于以下计划:
#include <stdio.h>
int main(int argc, char** argv)
{
int i;
void* p = &i;
printf("No cast, using %%p: %p\n",
p);
printf("Cast to unsigned long using conversion %%lx: %lx\n",
(unsigned long) p);
printf("Cast to unsigned long long using conversion %%llx: %llx\n",
(unsigned long long) p);
printf("Cast to unsigned long then unsigned long long using conversion %%llx: %llx\n",
(unsigned long long) (unsigned long) p);
return 0;
}
人们期望输出是什么?使用GCC 4.4.7进行编译并运行程序,并给出以下输出:
No cast, using %p: 0xbf8aa3d8
Cast to unsigned long using conversion %lx: bf8aa3d8
Cast to unsigned long long using conversion %llx: ffffffffbf8aa3d8
Cast to unsigned long then unsigned long long using conversion %llx: bf8aa3d8
使用clang 3.4版进行编译并运行程序会产生我真正期望的结果:
No cast, using %p: 0xbfa64234
Cast to unsigned long using conversion %lx: bfa64234
Cast to unsigned long long using conversion %llx: bfa64234
Cast to unsigned long then unsigned long long using conversion %llx: bfa64234
当直接从指针转换为无符号long long时,GCC似乎用1&#39;而不是0&#填充了最高有效位。这是GCC中的错误吗?
答案 0 :(得分:7)
这是根据draft C99 standard部分6.3.2.3
指针定义的实现,其中包含:
任何指针类型都可以转换为整数类型。除非事先指明,否则 结果是实现定义的。如果结果无法以整数类型表示, 行为未定义。结果不必在任何整数的值范围内 类型。
gcc
记录了实施here:
将指针转换为整数的结果,反之亦然(C90 6.3.4,C99和C11 6.3.2.3)。
如果指针表示大于,则从指针到整数的强制转换会丢弃最高有效位 整数类型,如果指针表示较小则为sign-extends1 比整数类型,否则位不变。
从整数到指针的转换会丢弃最高有效位 指针表示小于整数类型,扩展 根据整数类型的签名如果指针 表示大于整数类型,否则位是 不变。
或者您可以使用 uinitptr_t ,假设stdint.h
可用,这是一个可以保存指针值的无符号整数:
#include <stdint.h>
#include <inttypes.h>
uintptr_t ip = &i ;
printf("0x%016" PRIxPTR "\n", ip ) ;