以下类型转换在C中做了什么?

时间:2013-05-13 17:00:28

标签: c casting

我对C:

中的类型转换有疑问
void *buffer;

(int *)((int)buffer);

这种类型的铸造做什么?以及((int)buffer)做了什么?

3 个答案:

答案 0 :(得分:5)

想象一下,你和我一样在Linux / x86-64计算机上。那么指针是64位,int是32位宽。

因此,buffer变量已初始化为某个位置;也许是0x7fff4ec52020(可能是某个局部变量的地址,也许在main内)。

转换(int)buffer给你一个int,可能是最不重要的32位,即0x4ec52020

您正在使用(int*)((int)buffer)再次投射,它会为您提供虚假地址0x000000004ec52020,它不会指向有效内存。如果你取消引用那个虚假的指针,你很可能会得到一个SIGSEGV。

所以在某些机器上(特别是我的)(int *)((int)buffer) (int*)buffer不一样;

幸运的是,作为语句(int *)((int)buffer);没有明显的副作用,并且会被编译器优化(通过“删除”它)(如果你要求它进行优化)。 / p>

所以这样的代码是一个巨大的错误(可能会变成undefined behavior,例如,如果你取消引用那个指针)。如果原始编码器确实想要这里描述的奇怪语义,他应该添加注释(这样的代码是不可移植的)!

或许#include - 使用<stdint.h>并使用intptr_tuintptr_t可能更有意义。

答案 1 :(得分:2)

让我们看看C标准的内容。在上一个自由发布的C11标准http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf版本的第55页,我们有

  

5整数可以转换为任何指针类型。除非事先指明,否则   结果是实现定义的,可能没有正确对齐,可能不指向   引用类型的实体,可能是陷阱表示。

     

6任何指针类型都可以转换为整数类型。除非事先指明,否则   结果是实现定义的。如果结果无法以整数类型表示,   行为未定义。结果不必在任何整数的值范围内   类型。

这在你的例子中意味着什么?第6节说转换(int)buffer将编译,但如果整数不足以容纳指针(可能在64位机器上),结果是未定义的。最后的(int*)会转回指针。

第5节说如果整数 大到足以保存中间结果,那么结果与从一开始就转换为(int *)的结果完全相同。

简而言之,强制转换(int)最多是无用的,最坏的情况会导致指针值丢失。

答案 2 :(得分:0)

在直接C代码中,这是毫无意义的,因为来自void*的转换是隐含的。以下将编译得很好

int* p = buffer;

更糟糕的是,此代码可能会引入错误。考虑64位平台的情况。转换为int会将指针截断为32位,然后将其分配给int*。这将导致指针值被截断并且肯定会导致错误。