繁体   English   中英

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

[英]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_tuintptr_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM