我有一个程序将成为使用 C++ Builder 2010 构建的现有更大产品的一部分。
较小的程序(还)不依赖于 C++ Builder。它在 MS Visual Studio 中运行良好,但使用 C++ Builder 会产生奇怪的访问冲突。
请让我解释一下。
根据代码和编译器设置,访问冲突发生或不发生。访问冲突是可重现的:当程序构建时,访问冲突永远不会发生,或者总是在同一个地方发生。如果使用相同的设置重建程序,它将显示相同的行为。(我真的很高兴)。
访问冲突发生在调用删除运算符的地方。这可能发生在某些析构函数内部(取决于编译器设置和确切的代码),包括自身类的析构函数和 std::string 的析构函数内部。
以下情况降低了访问冲突的可能性:
- 使用“调试”设置(而不是“发布”)构建。
- 没有编译器优化。
- 编译器开关“慢速异常尾声”。
- 静态 RTL 而不是动态。
- 从 std::exception 而不是 Borland 的 Exception 类派生异常。
- 使用较少的“复杂”表达式(例如,使用“string s = “...” + “...”; throw SomeException(s);" 而不是 "throw SomeException(string("...") + ".. .");")
- 使用 try... __finally 进行手动清理,而不是使用带有析构函数的自动变量。
- 使用小型控制台应用程序而不是 VCL Windows 应用程序。
该程序利用了几个 C++ 特性,包括异常、STL、移动构造函数等,当然它也使用了堆。
我已经尝试了一些工具,但都没有报告问题:
- Borland 的 CodeGuard。
- Microsoft 应用程序验证器。
- 页堆/gflags。
- 如前所述,使用 MS Visual Studio 构建绝对没有问题。
预编译头文件和增量链接(在我看来都容易出错)的使用被禁用。
C++ Builder 编译器(“启用所有警告”)和 Visual Studio (/W4) 编译器都不会产生可能与此问题相关的警告。
我无权访问其他版本的 C++ Builder。
由于程序将成为更大产品的一部分,因此不能选择切换到不同的编译器,也不能选择调整编译器设置,直到不再发生访问冲突。(我担心如果这真的应该是编译器错误,那么该错误可能会再次出现。)
综上所述,我猜这可能是由于与某些编译器错误相关的堆损坏造成的。但是,我无法在 qc.embarcadero.com 上找到错误。我进一步猜测这与在抛出异常时堆栈倒带时执行的清理代码有关。但是,好吧,也许这只是一个愚蠢的代码错误。
目前,我不知道如何进行。任何帮助表示赞赏。先感谢您!