我正在以下无用的程序中在gcc中设置调试模式:
MyResource
,该程序让我知道我的索引越界。但是,如果翻转前两行的顺序,则不会收到此类错误消息(在#define之前#include)。为什么是这样?有没有办法在程序的另一行切换调试模式(没有编译器标志)?我问是因为我正在Leetcode.com上解决问题,在这里我无法通过编译器标志或修改问题的第一行。
答案 0 :(得分:3)
为什么必须在第一行中设置调试模式?
因为受宏影响的是标准库头。如果您之前包含标头,则包含的定义将看不到宏定义。考虑以下示例,并假设它是标准标头中包含的函数定义:
#define _GLIBCXX_DEBUG 1
inline void foo() {
#ifdef _GLIBCXX_DEBUG
std::cout << "debug mode is enabled";
#else
std::cout << "debug mode is not enabled";
#endif
}
与之相对:
inline void foo() {
#ifdef _GLIBCXX_DEBUG
std::cout << "debug mode is enabled";
#else
std::cout << "debug mode is not enabled";
#endif
}
#define _GLIBCXX_DEBUG 1
有没有办法在程序的另一行上切换调试模式(没有编译器标志)?
不包括标准标头。
在这种情况下,您可以使用std::vector::at
代替下标运算符。即使没有调试模式,它也会诊断超出范围的访问。
答案 1 :(得分:2)
任何以#…
开头的内容都是对C++ preprocessor的一条指令,该指令在实际的C / C ++编译器的之前运行;预处理程序为编译器构造最终的源代码。
这就是程序编译时发生的事情。
预处理器自上而下读取代码并执行指令。
#define _GLIBCXX_DEBUG 1
将名为_GLIBCXX_DEBUG
的标志设置为1
。
#include <vector>
#include <iostream>
从编译器的包含路径中读取文件vector.h
和iostream.h
。该文件包含更多的C / C ++代码以及预处理器指令,这些指令现在以递归方式展开。某些代码可能看起来像
#if _CLIBCXX_DEBUG
prinf("Print me to debug!");
#endif
,此代码将显示在最终的C / C ++中。如果您的_CLIBCXX_DEBUG
是0
,则代码将不存在。最终结果是您可以在编译之前将代码放在一起。
在您的情况下,额外的代码将特殊测试添加到最终的C / C ++文件中,这会导致您看到错误消息。当您切换线路时,处理#include
时不会设置该标志,因此不会将这些特殊测试添加到您的源中。
有关如何转储最终正在编译的最终C / C ++代码的信息,请参见this question。
一旦对C / C ++源代码文件进行了预处理(例如,包含了东西,有条件地展开等),然后将调用实际的编译器来构建代码。
有没有办法在程序的另一行上切换调试模式(没有编译器标志)?
根据需要在整个代码中更改该标志的值。