【发布时间】:2008-10-31 16:11:11
【问题描述】:
我继承了一个在VC8(VS2005)下构建和测试的非常庞大和复杂的项目(实际上是一个由119个“项目”组成的“解决方案”,其中大部分是DLL),我的任务是移植它到 VC9 (VS2008)。
我使用的移植过程是:
- 复制 VC8 .sln 文件并重命名 到 VC9 .sln 文件。
- 复制所有 VC8项目文件,并重命名 将它们添加到 VC9 项目文件中。
- 编辑 所有 VC9 项目文件, s/vc8/vc9。
- 编辑 VC9 .sln, s/vc8/vc9/
- 加载 VC9 .sln VS2008,让IDE“转换” 所有项目文件。
- 修复 编译器和链接器错误,直到我 构建良好。
到目前为止,我在最后一步中遇到了以下问题。
1) 修饰名称的计算方式发生变化,导致名称截断。
这不仅仅是一个警告 (http://msdn.microsoft.com/en-us/library/074af4b6.aspx)。使用此警告构建的库不会与其他模块链接。应用 MSDN 中给出的解决方案并非易事,而是可行的。我在How do I increase the allowed decorated name length in VC9 (MSVC 2008)?中单独解决了这个问题
2) 不允许将零分配给迭代器的更改。这是符合规范的,很容易找到并修复这些以前允许的编码错误。不要将零分配给迭代器,而是使用值 end()。
3) for 循环范围现在符合 ANSI 标准。另一个容易解决的问题。
4) 预编译头文件需要更多空间。在某些情况下,需要更多的空间。我最终使用 /Zm999 来提供最大的 PCH 空间。如果 PCH 内存使用量再次增加,我认为我将不得不完全放弃 PCH,并忍受已经很长的构建时间的增加。
5) 对复制 ctor 和默认 dtor 的要求进行了更改。似乎在模板类中,在我还没有完全弄清楚的某些条件下,编译器不再生成默认 ctor 或默认 dtor。我怀疑这是 VC9 中的一个错误,但可能还有其他我做错的事情。如果是这样,我肯定想知道它是什么。
6) sln 和 vcproj 文件中的 GUID 未更改。这似乎不会以任何我可以检测到的方式影响构建,但仍然令人担忧。
请注意,尽管存在所有这些问题,该项目还是在 VC8 下构建、运行并通过了广泛的 QA 测试。我还将所有更改移植到 VC8 项目中,它们仍然像以前一样愉快地构建和运行(使用 VS2005/VC8)。因此,我为 VC9 构建所需的所有更改至少看起来是向后兼容的,尽管回归测试仍在进行中。
现在解决真正棘手的问题:我遇到了 VC8 和 VC9 项目的启动顺序不同。该程序使用了一个仿照 Loki 的小对象分配器,在 Andrei Alexandrescu 的Modern C++ Design一书中。该分配器使用主程序模块中定义的全局变量进行初始化。
在 VC8 下,这个全局变量是在程序启动的最开始,从模块 crtexe.c 中的代码构造的。在VC9下,第一个执行的模块是crtdll.c,表示启动顺序发生了变化。正在启动的 DLL 通过在全局对象初始化统计信息之前分配和释放内存来混淆小对象分配器,这会导致一些虚假的诊断。程序的运行似乎没有受到实质性影响,但 QA 人员不会让虚假诊断通过他们。
有没有办法在加载 DLL 之前强制构建一个全局对象?
我可能会遇到哪些其他移植问题?
【问题讨论】:
标签: visual-c++ visual-c++-2008 name-decoration vc8