大多数的编译器能发现类型的不匹配,并能在构建期间纠正它们,这对如传递给函数的参数这样大多数的简单赋值来说是正确的。而真正的问题在于,对int、long、指针之间的不匹配,编译器在编译期间却视而不见,或者说编译器在编译期间所做的假设,导致了这种不匹配问题依然存在。前者涉及指针参数及函数指针,而后者主要是有关于函数原型。 逆风者
传递一个int和long指针作为函数参数时,如果这个指针之后被解引用为一个不同的、不兼容的类型,也会导致问题。这种情况不是32位代码的问题,而是因为ing与long是不可互换的。但是,在64位代码中,却因为指针与生具有的可伸缩性,这种情况将导致运行时错误,大多数编译器假定你正在做的事情,就是你想要做的事情,所以会悄无声息地对此问题放行,除非打开更多的警告信息。而通常只有在程序运行时,此问题才会浮出水面。
举例来说,例1可同时在Solaris和AIX(Frote7、VAC 6)的32位与64位模式中通过编译,而没有任何警告,然而,64位的版本运行时却输出不正确的值。在如此短的示例中,这种问题很容易被发现,如果在更大型的代码中呢,恐怕会难多了吧。这种类型的问题可隐藏在现实中实际的代码里,而大多数的编译器却不能发现它们。
例1:
#include <stdlib.h> #include <stdio.h>
int Func1(char *);
int main() { long arg, ret; arg = 247; ret = Func1((char *)&arg); printf("%ld\n", ret); return(0); } int Func1(char * input) { int *tmp; tmp = (int *)input; return(*tmp); }
当作为64位可执行程序运行于小字节序机器上时,例1显得一切正常,因为arg的值完全包含在long的四个最少有意义的字节中。然而,甚至在小字节序的x86机器上,当arg的值超出了四个最少有意义的字节时,64位的版本也会在运行期间产生一个错误。
正是因为函数指针,编译器无法获取信息,以确定哪一个函数将会调用,因此它不能纠正或警告你有关可能存在的类型不匹配问题,所有通过特定函数指针调用的函数参数与返回类型都在此范围之内。如果想从根本上纠正此问题,你必须提供一种分离的方案,在函数调用时对参数及返回值进行适当的类型转换。
第二个问题涉及隐式函数声明,如果没有对代码中调用的每一个函数提供一个原型,编译器就会做出假设。编译器产生的类似警告信息"Implicit function declaration: assuming extern returning int"在32位构建时通常是无关紧要的;但在64位构建时,这种返回值是int的假设,当函数实际上是返回long或指针(例如malloc)时,就会导致真正的问题了。为了不让编译器做出这种假设,必须确保所有需要的系统头文件都包含或提供了外部函数的函数原型。
[1][2][3]下一页 本文章更多内容:<<上一页 - 1 - 2 |