swap1.c出错,汇编如下
很明显,main.c的汇编代码中p指向的是data, 虽然我们觉得data和p值应该相等,但编译器却不这么认为。
在extern int * p中movl p, %eax先取出p的值(data地址)给eax, 然后再操作,也就是说data和p值是不同。 虽然我们在应用层中看到p==data是对的,那是因为编译器做了同样改动movl p, %eax,也就是所谓的“隐形转换”, 然后比较eax和data地址自然相等。
在编译器眼里,main.c中申明的data作为一个对象(object), p作为指针, 二者根本不是一回事,如果要对二者进行相关操作只能先帮你隐形转换,而这却被我们视为相同。
所以如果extern int * data, 编译器会在swap1.c中将data视为指针,实际声明在main.c中的是对象,但编译器以为你懂且有意为之,它必须按指针的操作方式处理data。
假定是64位的编码模式,即地址长度为64。swap1.c执行data=0,编译器认为对指针变量(64位)取0那就直接movl $0, data呗,则data[0]和data[1]就被覆盖为0。实际上如果extern要声明data为指针,任何指针都行,不局限于int, 反正data早已不是对象。
总之说白了就是extern引用的对象被你更换类型成了指针,你误以为没事,不了解编译器对二者是不同对待。