提问动机:生成 64 位和 32 位代码需要两个单独的完整程序编译,并且在使用 visual studio(如下详述)时,发布和调试版本不兼容,因此似乎需要另外两个完整的程序编译(使总数达到四个)。我想坚持使用两个完整的程序编译,但我很困惑。
调试时,我只关心:全局状态、堆栈帧和导致崩溃的代码的行号/文件。此外,我不关心来自同行评审的高度稳定的开源库的调试信息;因此,我不需要这些库的调试信息,并且这些库的发布版本应该足够了。
证据:我知道,在 VS 中,如果您编译应用程序的调试版本并将其与 Google Protocol Buffers 的发布版本链接,则生成的代码将因以下原因而失败:混合发布/调试类型的影响。
我想知道这是否是使用 visual studio 的副作用,并且特定的一组编译器开关使它如此。
其次检查开源项目的构建脚本/过程,似乎可以将 Debug模式下生成的代码与 Release模式下生成的代码混合使用(例如 mumble)。我想这与 release 和 ReleaseWithDebugInfo 之间的区别有关(从 cmake 借用的术语,但这显然可以在 Visual Studio 中表达)。 ReleaseWithDebugInfo 毕竟是二进制文件的优化版本,还会生成调试信息,因此适合发布。
问题:
- 有人可以解释或提供引用,说明哪些开关使代码不兼容。
- Visual Studio 中的 ReleaseWithDebugInfo 编译风格是否足以用于调试和发布用例(根据我的标准,如上所述)? -- 即编译器在 Debug模式下生成的任何内容是否过度或多余?
- 在 ReleaseWithDebugInfo 模式下(对于我的应用程序)我可以在 Release模式下编译外部依赖项(没有调试信息)并且没有任何未定义的行为吗?
最佳答案
Debug模式(我认为你的意思是未优化)代码是否“矫枉过正”取决于你想用它做什么。
如果您想使用调试器、非常准确地步进行并检查遇到的任何变量,则需要关闭优化。如果您对此不太在意,则可以将其打开,并在调试器中忍受一些奇怪的行为。
如果您为“编辑并继续”进行编译,则会在该位置周围放置大量填充以允许部分编译/链接。
因此,未优化的代码存在很多“矫枉过正”和“冗余”,但它们可能仍然有值(value)。
链接不同配置的常见问题是当它们共享由运行时库的不同版本/配置分配的对象时。如果您在库之间使用 Win32 风格的“C”风格接口(interface),那么您很少关心一个人的调试和一个人的发布。如果您使用一个运行时版本在堆上分配一个 CString,然后将它传递给使用不同运行时解除分配的代码,那么通常会出现问题。
在这里您需要考虑三件不同的事情:
- 我需要调试符号吗? - 您可以在任何调试/发布配置中制作这些
- 我需要良好的可调试性还是需要良好的代码优化?
- 每个人都使用什么 CRT/STL/什么版本?
这只是您真正需要达到完美的最后一个。其他两个是个人喜好。
关于visual-c++ - MSVC 混合调试代码和发布代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4133738/