我使用的移植过程如下:
1. 复制VC8 .sln文件并将其重命名为VC9 .sln文件。 2. 复制所有VC8项目文件,并将它们重命名为VC9项目文件。 3. 编辑所有VC9项目文件,将vc8替换为vc9。 4. 编辑VC9 .sln文件,将vc8替换为vc9。 5. 使用VS2008加载VC9 .sln文件,并让IDE“转换”所有项目文件。 6. 修复编译器和链接器错误,直到获得良好的构建。
到目前为止,在最后一步中我遇到了以下问题:
1. 改变了装饰名称计算的方式,导致名称被截断。这不仅仅是一个警告,(http://msdn.microsoft.com/en-us/library/074af4b6.aspx)。使用此警告构建的库将无法与其他模块链接。应用MSDN中给出的解决方案很困难,但可行。我在这里单独解决了这个问题。
2. 更改不允许将零分配给迭代器。这是根据规范,以前允许的编码错误很容易找到和修复。使用end()值代替向迭代器赋值为零。
3. for循环作用域现在符合ANSI标准。一个易于解决的问题。
4. 预编译头需要更多空间。在某些情况下,需要更多的空间。我最终使用/Zm999提供最大的PCH空间。如果PCH内存使用率再次增加,我认为我将不得不放弃PCH,只需忍受已经非常长的构建时间的增加。
5. 复制构造函数和默认析构函数的要求发生了变化。在模板类中,似乎在某些条件下编译器不再生成默认构造函数或默认析构函数。我怀疑这是VC9中的一个错误,但可能还有其他我做错了的事情。如果是这样,请告诉我具体是什么。
6) sln和vcproj文件中的GUID没有更改。据我所知,这似乎并不会对构建产生影响,但仍然令人担忧。
需要注意的是,尽管存在所有这些问题,该项目在VC8下构建、运行并通过了广泛的QA测试。我还将所有更改回溯到了VC8项目中,在那里它们仍然像以前一样愉快地构建和运行(使用VS2005 / VC8)。因此,我为VC9构建所需的所有更改至少看起来是向后兼容的,尽管回归测试仍在进行中。
现在是真正困难的问题:我遇到了VC8和VC9项目之间启动顺序的差异。程序使用一个类似于Loki的小对象分配器,模仿Andrei Alexandrescu的书《现代C++设计》。该分配器使用在主程序模块中定义的全局变量进行初始化。
在VC8下,此全局变量在程序启动的最开始从crtexe.c模块中的代码中构造。在VC9下,执行的第一个模块是crtdll.c,这表明启动顺序已更改。正在启动的DLL似乎通过在全局对象可以初始化统计信息之前分配和释放内存来混淆小对象分配器,这导致了一些虚假诊断。程序的操作似乎没有受到实质性影响,但QA人员不会允许虚假诊断通过。
是否有一种方法可以在加载DLL之前强制构造全局对象?
我可能会遇到哪些其他移植问题?