Visual C++ 6.0到Visual C++ 2005的移植

Visual C++ 6.0 到Visual C++ 2005 的移植
 
         尽管Visual C++ 2005中的变化,代表了对从90年代中期开始的与ISO C++不兼容的一个重大改进,但因为担心损害现有的C++程序,大多数的开发人员都不愿意升级。而本文旨在帮助定位与修复那些不兼容的代码,以便平滑、无后顾之忧地升级你的程序。
 
         在Visual C++ 2005中,最大的变化在于核心C++的升级,这意味着全面遵循ISO C++标准,无须置疑,这些都是对那些从90年代中期开始的不兼容性的一个重大改进,而此时,我们面临一个利弊双趋的选择:移植到到Visual C++ 2005需要一个彻底的代码审阅,可能还要进行一些必要的修改。在本文中,将要说明在移植现有的Visual C++ 6.0程序到Visual C++ 2005中时,哪些地方是必须要留意的。
 
 
         代码审阅与分析
         Visual C++的早期版本实 际上是在强制程序员编写与ISO C++不兼容的C++代码,因此,一个现有的Visual C++ 6.0程序不太可能原封不动地通过Visual C++ 8.0的编译——Visual C++ 8.0是Visual Studio 2005中的C++编译器;所以,移植的第一步必须重新审阅代码,并找出潜在的问题。在对代码作出修改之前,此处的建议是,必须要审阅完全部的代码,并有 系统地标记出所有可能与Visual C++ 2005不兼容的代码段,且只对必要的地方作出修改,此过程最好重复几遍,每遍只处理同一类范畴问题,例如,第一遍可以集中在for循环上,下一遍可以审 阅异常处理,如此下去。以下是支持此分种类修改代码的三个理由:
 
² 团队工作:正所谓术业有专攻,专攻于不同的领域的开发者可同时对同一代码进行审阅。
² 编码标准:当一次只处理一种问题时,很容易执行相应的统一编码标准。
² 基于关键字的查找:每一次审阅可只关联到某一特定的C++关键字(例如:要定位for循环,可查找关键字for)。
 
 
代码修改
         一些必要处的代码修改必须直接了当,包换for循环、指向成员函数的指针、忽视了默认为int类型、异常处理等等。来看一下这意味着什么:
 
² for 循环:在标准化之前的C++中,for循环中声明的变量在表示循环区域的花括号之外,都是可见的,这一直沿袭到Visual C++ 6.0中: for (int i=0; i<MAX; i++) { //..do something } int j=i; //VC++ 6.0中允许这样做 然而,在Visual C++ 2005中,变量i的范围被限制在for循环当中。如果想在花括号之外引用此变量,请把变量的声明移出for循环: int i=0; for (; i<MAX; i++) {  //..do something } int j=i; //OK
² 成 员指针的声明:在标准化之前的C++中,不用&操作符,就能取一个成员函数的地址: struct S {  void func(); }; void (S::*pmf)() = S::func; //在VC++ 6.0允许这样做 而在Visual C++ 2005中,&操作符是强制性的: void (S::*pmf)() = &S::func; //OK
² 默 认为int类型:在标准化之前的C++中(也包括C99标准之前的所有C语言变量),当声明函数和变量时,如果没有指定类型,都会使用“默认为int类 型”这条潜规则,而这一直保持到Visual C++ 6.0中,如下所示: const x=0; //隐示为int static num; //隐示为int myfunc(void *ptr); //返回类型隐示为int 而在Visual C++ 2005中,则必须显示指定数据类型: const int x=0; static int num; int myfunc(void *ptr); 提示:要找出此类不兼容代码,只需用Visual C++ 2005重新编译程序,然后查找那些关于在声明中缺少数据类型的编译器错误。
² 异 常处理:在早期版本的Visual C++中,混合了标准C++异常与异步结构化异常处理(SEH)。因此,一个catch()语句块不仅能捕捉到throw语句抛出的一个C++异常,还能 捕捉到一个异步SEH,如访问违例,这种行为不仅不兼容现行的C++标准,还使得调试更加困难。Visual C++ 2005修正了此行为,通过默认的/Ehsc设置,现在可以指定是否一个catch()块只捕捉C++异常——而这也是推荐选项,或者为保持与 Visual C++ 6.0一致,使用/Eha设置,见图1。
 
图1
 
此处需注意的是,以上并没有反映 Visual C++ 2005中全部的新变化,若需查看详细信息,请查阅Visual C++ 2005的主页。另外,本节主要讲述核心C++的功能,其他特定于Visual C++的变化,如多线程CRT、不推荐使用的API等等,本文都没有讨论。
 
 
         数据类型
         Visual C++ 2005与Visual C++ 6.0有着不同的应用程序二进制接口(ABI),也就是说,相同的数据类型或函数可能有着不同的二进制格式和不同的内部名,这些不同的ABI尤其会影响到std::time_t和wchar_t数据类型。
         Visual C++ 6.0把std:: time_t当成一个32位的整数,但在Visual C++ 2005中,此类型是一个64位的整数,此时,如果你的程序中把time_t当作了一个32位的整数来用,如硬编码的缓冲区大小等等,那么在升级时就必须 作出必要的修改了。另外,ABI也同时影响到wchar_t类型的表示形式,直到目前为止,wchar_t还是一个typedef unsigned short的同义词,然而,Visual C++ 2005却把wchar_t当作一个内置类型,而此可能会影响到函数的重载:
 
int _wtolowers(unsigned short *ws);
wchar_t ws[10] = L"Test";
_wtolowers(ws);
 
         此段代码可在Visual C++ 6.0中通过编译,但在Visual C++ 2005中却不行,因为wchar_t * 已经与unsigned short * 不再兼容。
 
         本文中所提到的问题,不仅会影响到 Visual C++ 6.0到Visual C++ 2005的移植,而且,在通常意义上来说,也会影响到老式C++代码向ISO C++标准的移植,而这正是导致项目经理推迟升级的主要原因,虽然这种想法是不对的。但从总体来看,Visual C++ 2005的这些变化只是C++发展的必经阶段,现在修改代码升级程序,也会为将来进一步的升级,打下坚实的基础。

你可能感兴趣的:(多线程,C++,c,api,struct,编译器)