使用带有-g 选项的 g++ ,我可以使用 gdb 进行调试。
Visual Studio 2010 cl.exe 编译器与此选项等效的是什么?
此页面具有用于链接的不同库(调试/发布)。
如果我使用 cl.exe 使用调试选项进行编译,是否必须使用相应的库链接选项(/MD/MT vs /MDd/MTd)?
这个问题有几个单独的部分:如何告诉编译器/链接器生成和保留“调试信息”(源代码和目标代码之间的映射),如何告诉编译器以不同的方式编译代码以使调试更容易(想想 assert() 和 #ifdef _DEBUG),以及链接到项目中的预编译库是否包含调试信息。
-Zi(指示 CL 编译器生成调试信息的标志)相当于 gcc 的 -g 标志。
(还有其他形式的 -Z 选项:-ZI 如果您想要 Visual Studio IDE 中的“编辑并继续”支持,但如果您使用的是 IDE,您可能使用的是编译器设置的接口而不是直接操作它们,如果你想要旧的 CodeView 格式的调试信息,则使用 -Z7;每当我直接调用 CL 时,我想要的总是 -Zi。)
请注意,使用 -Zi(或 -ZI)选项通常会为每个目录生成一个 .pdb 文件,但是当您将代码链接在一起时,它可能来自不同 .pdb 文件中表示的 .obj 文件,您还希望将这些单独的 .pdb 文件组合成一个主文件,代表您链接在一起的代码——这就是链接器的 -debug 开关的用途。
另请注意:这听起来可能违反直觉,但始终使用 -Zi(用于 CL)和 -debug(用于 link.exe)。即使是你要发布的代码。它不会增加可执行文件的大小,也不会向客户泄露机密,因为调试信息位于单独的 .pdb 文件中(您不会将其发送给客户)。如果您有任何机会必须对其进行调试,那么您将需要 .pdb。(-Zi 甚至与优化不兼容,尽管 -ZI 是。所以你可能想用 -ZI 编译你的“调试”版本,而你的“发布”版本用“-Zi -O2”编译。)
至于库:您不需要严格匹配 C 运行时库的调试/发布属性与您的代码是否包含调试信息,但这通常是一个好主意——如果您要调试您想要的项目能够调试所有它,如果你不打算调试它,你不需要额外的重量。使用给定库的调试/发布版本不会影响它是否具有可用的调试符号(希望,如果编译该库的人理解我在上一段中提出的观点),但它会影响诸如断言和额外的 #ifdef _DEBUG 之类的东西该库中的代码。
这适用于您链接的所有库,尤其是 C 运行时库——微软在 malloc() 和 free() 中添加了额外的错误检测代码。因此,如果您的项目中的任何内容都在使用 CRT 库的调试风格,那么所有这些都应该是。
/M 选项(/MTd 和 /MDd)在我看来既奇怪又神奇——它们只是幕后发生的一组复杂的其他事情的别名。以 /MDd 为例,记录为“定义 _DEBUG、_MT 和 _DLL 并导致您的应用程序使用运行时库的调试多线程和 DLL 特定版本。它还导致编译器将库名称放置为 MSVCRTD。 lib 到 .obj 文件中。” 在这里,它同时影响预处理器(定义 _DEBUG 和一些其他预处理器符号)和链接器(它实际上在源代码中放置了 #pragma 注释(链接器))。如果您关心正在发生的事情并且不理解它,这可能会导致真正的问题——我已经看到很多不使用 IDE 的项目都陷入了关于 msvcrt.lib 和 msvcrtd.lib 的警告中被链接,等当您了解如何安全地使用这些(/M 选项)时,您就不再需要它们了!我更喜欢明确说明:在我需要的地方直接指定“-D _DEBUG”,指定要显式链接的库(并使用 -nodefaultlib),然后不需要 /M 选项。