强制类型转换的内部实现?

104 views
Skip to first unread message

黄虎才

unread,
Oct 8, 2009, 2:23:20 AM10/8/09
to 西邮Linux兴趣小组
我们在编写程序的时候,经常会使用到强制类型转换,例如有一个结构体
struct S {
        ...
        int number;
};
有下面这样一段代码:
int a = 90;
typeof(((struct S *) 0)->number) *p = &a;
当然,我们知道,现在p指向的是变量a的地址,现在问题就是,这里将常数0强制转换为指向结构体struct S的指针,
而这样的强制类型转换是怎样实现的呢?谢谢

Kermit Mei

unread,
Oct 8, 2009, 2:50:06 AM10/8/09
to 黄虎才, 西邮Linux兴趣小组

找一本《编译原理》看看你就明白了。我试着解释一下(放很久了,不知道有没有
记错,如有错误请指正):
在类似C这种语言的实现中,编译器会维护一个叫符号表的东西,那里面记录着变
量标识,变量的内存地址和变量的类型等,编译器会根据这些信息来决定如何处理
这个变量。
强制类型转换,实质上就是在传递参数或者赋值的时候,把符号表中的类型改变了
一下再继续操作(赋值或传参数)。

那时候没有怎么好好学《编译原理》,一则没时间,二则也看不大懂……
现在看来,能够决定你能力的最本质的东西还是李开复先生所讲的那四门最核心的
课程:
《算法》,《操作系统》,《数据库》和《编译原理》

扯远了,就此打住,呵呵……


Have fun!

Kermit Mei


李则良

unread,
Oct 8, 2009, 3:07:30 AM10/8/09
to 黄虎才, 西邮Linux兴趣小组
2009/10/8 黄虎才 <china...@gmail.com>:
其实,所谓类型无非就是固定了空间的分配格式,比如,C语言中简单的int类型,就是从某一个地址开始分配4Bytes(32位体系架构下),结构体也是如此。
可以这样总结定义类型:起始地址+空间大小以及空间格式
这样想的话,上面就好理解了:
(struct S *) 0 就是以0作为起始地址,空间大小4Bytes(struct S *是指针类型)
((struct S *) 0)->number 就是取指针所指向类型的number成员

typeof(((struct S *) 0)->number)
将取得number成员的类型,其实这一句的结果就是int,如果你在S中定义number为其它类型,那么结果就是其它相应的类型,剩下的就不必解释了。
如果还想更深入的理解,那就看看gcc是怎样实现typeof的了,这篇文章可以拿来参考一下:
http://www.diybl.com/course/6_system/linux/Linuxjs/20071210/91287.html
>

--
KISS == Keep it simple,stupid~:-)

WANG Cong

unread,
Oct 8, 2009, 4:28:58 AM10/8/09
to 黄虎才, 西邮Linux兴趣小组
这里的强制转换只是为了得到->number的类型,编译时编译器会分析得出。

这和其它一些转换还不一样,比如:

int a = 0xf0000000;
short b;
b = (short) a;

这个转换就会直接影响生成的汇编。

黄虎才

unread,
Oct 9, 2009, 5:46:00 AM10/9/09
to WANG Cong, 西邮Linux兴趣小组


2009/10/8 WANG Cong <xiyou.w...@gmail.com>

   这个星期周四,小组进行的讲座内容中涉及到了这个知识点,也是在讲座的过程中明白了到底是怎么回事,就是一句话:
   这里提到的通过类型转换而得到的计算结果是由编译器来完成的.

Helight.Xu

unread,
Oct 9, 2009, 6:04:42 AM10/9/09
to 黄虎才, WANG Cong, 西邮Linux兴趣小组
黄虎才 wrote:
> 2009/10/8 WANG Cong <xiyou.w...@gmail.com>
>
>
>> 黄虎才 <china...@gmail.com> writes:
>>
>>
>>> 我们在编写程序的时候,经常会使用到强制类型转换,例如有一个结构体
>>> struct S {
>>> ...
>>> int number;
>>> };
>>> 有下面这样一段代码:
>>> int a = 90;
>>> typeof(((struct S *) 0)->number) *p = &a;
>>> 当然,我们知道,现在p指向的是变量a的地址,现在问题就是,这里将常数0强制转换为指向结构体struct S的指针,
>>> 而这样的强制类型转换是怎样实现的呢?谢谢
>>>
typeof(a)是获取a的类型,如果a是int那么typeof(a) b就相当于int b。

((struct S *) 0)->number 其实是将0地址强制转换为一个 struct S 类型的指针,
然后获取了其中的number成员。

>>> ((struct S *) 0)->number只是获取0


>> 这里的强制转换只是为了得到->number的类型,编译时编译器会分析得出。
>>
>> 这和其它一些转换还不一样,比如:
>>
>> int a = 0xf0000000;
>> short b;
>> b = (short) a;
>>
>> 这个转换就会直接影响生成的汇编。
>>
>>
>
> 这个星期周四,小组进行的讲座内容中涉及到了这个知识点,也是在讲座的过程中明白了到底是怎么回事,就是一句话:
> 这里提到的通过类型转换而得到的计算结果是由编译器来完成的.
>
> >
>


--
---------------------------------
Zhenwen Xu - Open and Free
Home Page: http://zhwen.org

黄虎才

unread,
Oct 9, 2009, 9:47:09 AM10/9/09
to Helight.Xu, WANG Cong, 西邮Linux兴趣小组


2009/10/9 Helight.Xu <helig...@gmail.com>
黄虎才 wrote:
> 2009/10/8 WANG Cong <xiyou.w...@gmail.com>
>
>
>> 黄虎才 <china...@gmail.com> writes:
>>
>>
>>> 我们在编写程序的时候,经常会使用到强制类型转换,例如有一个结构体
>>> struct S {
>>>         ...
>>>         int number;
>>> };
>>> 有下面这样一段代码:
>>> int a = 90;
>>> typeof(((struct S *) 0)->number) *p = &a;
>>> 当然,我们知道,现在p指向的是变量a的地址,现在问题就是,这里将常数0强制转换为指向结构体struct S的指针,
>>> 而这样的强制类型转换是怎样实现的呢?谢谢
>>>
typeof(a)是获取a的类型,如果a是int那么typeof(a) b就相当于int b。

((struct S *) 0)->number 其实是将0地址强制转换为一个 struct S 类型的指针,
然后获取了其中的number成员。

这是编译器来完成的
Reply all
Reply to author
Forward
0 new messages