3

问题的动机:生成 64 位和 32 位代码需要两个单独的完整程序编译,并且在使用 Visual Studio(如下详述)时,发布和调试版本不兼容,因此似乎需要另外两个完整程序编译(使总数达到四个)。我想坚持使用两个完整的程序编译,但我很困惑。

调试时我只关心:全局状态、堆栈帧以及导致崩溃的代码的行号/文件。另外,我不关心来自同行评审的高度稳定的开源库的调试信息;因此,我不需要这些库的调试信息,并且该库的发布版本应该足够了。

证据:我知道,在 VS 中,如果您编译应用程序的调试版本并将其与 Google Protocol Buffers 的发布版本链接,则生成的代码将由于混合发布/调试类型的副作用而失败。

我想知道这是否是使用 Visual Studio 的副作用,并且某些编译器开关可以做到这一点。

其次检查开源项目的构建脚本/过程,似乎可以将调试模式生成的代码与发布生成的代码混合(例如mumble)。我想这与 release 和 ReleaseWithDebugInfo (从 cmake 借用的术语,但这显然可以在 Visual Studio 中表达)之间的区别有关。ReleaseWithDebugInfo 毕竟是二进制的优化版本,还生成了调试信息,因此适合发布。

问题:

  1. 有人可以解释或提供参考,什么开关使代码不兼容。
  2. Visual Studio 中的 ReleaseWithDebugInfo 编译风格是否足以用于调试和发布用例(根据我的标准,如上所述)?--ie,编译器在调试模式下生成的东西是矫枉过正还是多余?
  3. 在 ReleaseWithDebugInfo 模式下(对于我的应用程序)我可以在发布模式下编译外部依赖项(没有调试信息)并且没有任何未定义的行为吗?
4

1 回答 1

4

调试模式(我认为你的意思是未优化)代码是否“过度杀伤”取决于你想用它做什么。

如果您想使用调试器,非常准确地步进行并检查您遇到的任何变量,您需要关闭优化。如果您对此不太在意,则可以将其保持打开状态,并在调试器中忍受一些奇怪的行为。

如果您为编辑并继续进行编译,则会在该位置周围放置大量填充以允许部分编译/链接。

因此,未优化的代码有很多“矫枉过正”和“冗余”,但它们可能仍然很有价值。

链接不同配置的常见问题是当它们共享由运行时库的不同版本/配置分配的对象时。如果您在库之间使用 Win32 风格的“C”风格接口,那么您很少关心一个是调试还是一个发布。如果您在堆上分配一个运行时版本的 CString,然后将其传递给使用不同运行时解除分配的代码,那么通常会出现问题。

您需要在这里考虑三件不同的事情:

  • 我需要调试符号吗?- 您可以在任何调试/发布配置中进行这些操作
  • 我需要良好的可调试性还是需要良好的代码优化?
  • 每个人都在使用什么 CRT/STL/什么版本?

这只是你真正需要变得完美的最后一个。另外两个是个人喜好。

于 2010-11-09T12:56:17.243 回答