[英]what does the following type casting do in C?
我对C中的类型转换有疑问:
void *buffer;
(int *)((int)buffer);
这种类型的铸造做什么? 和((int)buffer)
做什么?
想象一下,你和我一样在Linux / x86-64计算机上。 那么指针是64位, int
是32位宽。
因此, buffer
变量已初始化到某个位置; 也许0x7fff4ec52020(可能是某些局部变量的地址,也许在main
内部)。
cast (int)buffer
为您提供了一个int,可能是最低有效32位,即0x4ec52020
您正在使用(int*)((int)buffer)
再次强制转换,它会为您提供虚假地址0x000000004ec52020,它不会指向有效内存。 如果你取消引用那个虚假的指针,你很可能会得到一个SIGSEGV。
所以在某些机器上(特别是我的) (int *)((int)buffer)
与 (int*)buffer
;
幸运的是,作为语句 , (int *)((int)buffer);
没有明显的副作用,并将由编译器优化(通过“删除”它)(如果你要求它进行优化)。
所以这样的代码是一个巨大的错误(可能会成为一个未定义的行为 ,例如,如果您取消引用该指针)。 如果原始编码器真的想要这里描述的奇怪语义,他应该添加注释(并且这样的代码是不可移植的)!
也许#include
-ing <stdint.h>
并使用intptr_t
或uintptr_t
可能更有意义。
让我们来看看C标准的内容。 在最后一个免费发布的C11标准版本的第55页http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf我们有
5整数可以转换为任何指针类型。 除非先前指定,否则结果是实现定义的,可能未正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。
6任何指针类型都可以转换为整数类型。 除了之前指定的以外,结果是实现定义的。 如果结果无法以整数类型表示,则行为未定义。 结果不必在任何整数类型的值范围内。
这在你的例子中意味着什么? 第6节说cast (int)buffer
将编译,但如果整数不足以容纳指针(可能在64位机器上),结果是未定义的。 final (int*)
强制转换为指针。
第5节说,如果整数是大到足以容纳中间结果,结果是完全一样的从一开始就只是投放,与(int *)相同。
简而言之,cast (int)
最多是无用的,最坏的情况是导致指针值丢失。
在直接的C代码中,这是毫无意义的,因为进出void*
转换是隐含的。 以下编译就好了
int* p = buffer;
更糟糕的是,此代码可能会引入错误。 考虑64位平台的情况。 转换为int
会将指针截断为32位,然后将其指定给int*
。 这将导致指针值被截断并且肯定会导致错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.