指针强制转换在指令变量赋值上,只是编译器的一个善意的提醒,在汇编语言中,和不加强制转换的指令时一样的,并没有多产生指令。强制转换后的影响不是在转换的时候发生,而是在用转换后的身份去访问内存时体现到了指令中。
例子:
6: int i; //globle variable
7: int *pi; //globle variable
8: short *ps; //globle variable
9: char *pc; //globle variable
10:
11: int _tmain(int argc, _TCHAR* argv[])
12: {
13:
14: pi = &i;
003317BE mov dword ptr ds:[003374BCh],3374C0h
15: ps = (short *)i;
003317C8 mov eax,dword ptr ds:[003374C0h]
003317CD mov dword ptr ds:[003374B8h],eax
16: pc = (char *)i;
003317D2 mov eax,dword ptr ds:[003374C0h]
003317D7 mov dword ptr ds:[003374B4h],eax
17: *pi = 0x1234;
003317DC mov eax,dword ptr ds:[003374BCh]
003317E1 mov dword ptr [eax],1234h
18: *ps = 0x1234;
003317E7 mov eax,1234h
003317EC mov ecx,dword ptr ds:[003374B8h]
003317F2 mov word ptr [ecx],ax
19: *pc = 0x12;
003317F5 mov eax,dword ptr ds:[003374B4h]
003317FA mov byte ptr [eax],12h
20:
21: return 0;
003317FD xor eax,eax
22: }
14.15.16这三行是对指针变量的赋值语句,我们通过反汇编代码可以看到只是单纯的将变量i的地址赋值给了pi,ps, pc这三个指针变量,并没有涉及到指针类型。
再看17.18.19这三行,表面上看起来和强制转化无关的赋值语句。这三句是对同一地址(即i的地址)以三种不同身份进行的赋值操作,我们看到mov指令后面分别跟的是dword,word,byte,说明三种mov指令分别向内存中写4字节,2字节,1字节。此时可知强制转换类型发生了作用。
强制转换的安全问题
如果转换后指针指向的数据类型大小小于原数据类型大小,那么用转换后的指针访问时安全的,否则是危险,要越界。
通俗的来说就强制转化只能从大往小转,转换后你只能吃亏,要是转换后能多访问了几个字节,那编译器就会告诉你这是不可以的。