64位机器指针仅用24位表示?指针类型转换是否为UB?
问题解答
1. 为什么指针值仅显示24位而非64位?
%p格式符打印指针时会自动省略地址的前导零。在64位系统中,你的指针实际值是0x00000000004005e4,但高位无意义的0000000000会被省略,最终输出0x4005e4——本质上它仍是完整的64位地址,只是显示时做了简化。
2. (char *)(int)s这类不同大小的指针转换是否属于未定义行为?
在64位系统中,int通常为32位,指针为64位,这类跨大小的转换要分情况看:
- 将64位指针转成32位
int:如果指针地址值超出int的可表示范围(比如高位非零),结果属于实现定义行为(具体处理逻辑由编译器决定);如果地址值在int范围内(比如你的例子中的低地址),转换结果确定,但这仍是不推荐的写法。 - 将32位
int转回64位char*:只有当这个int值是从同类型指针转换而来且未丢失地址信息时,结果才是原指针;否则行为可能未定义(比如高位补零后得到无效地址)。
C标准推荐用<stdint.h>中的uintptr_t或intptr_t类型做指针与整数的转换,这些类型的大小专门匹配指针宽度,能避免大小不匹配的问题。
3. 为什么预期(char)s输出1字节地址,却打印了8字节?
你代码中实际写的是(char*)(int)s,这是把int转回了char*指针类型,而char*在64位系统中是8字节,所以%p会按指针格式打印它的完整地址(同样省略前导零)。
如果是(char)s,那是将指针截断为1字节的char类型,但用%p打印时,由于printf的可变参数特性,char会被隐式提升为int,而%p要求参数是指针类型,这种类型不匹配属于未定义行为,打印结果不可预测——%p本身不支持打印单个字节的数值,它只用于输出指针地址。
内容的提问来源于stack exchange,提问作者Milan
相关产品推荐
相关产品推荐

