繁体   English   中英

为什么必须在第一行中设置_GLIBCXX_DEBUG?

[英]Why does _GLIBCXX_DEBUG have to be set in first line?

我在以下无用程序中的gcc中设置调试模式:

#define _GLIBCXX_DEBUG 1
#include <vector>
#include <iostream>
using namespace std;
int main() {
    vector<int> v{1,2,3};
    for(int i=0; i<100000000000000;i++)
    cout<<v[i];
}

该程序让我知道我的索引超出范围。 但是,如果翻转前两行的顺序,则不会收到此类错误消息(在#define之前#include)。 为什么是这样? 有没有办法在程序的另一行切换调试模式(没有编译器标志)? 我问是因为我正在Leetcode.com上解决问题,在这里我无法通过编译器标志或修改问题的第一行。

为什么必须在第一行中设置调试模式?

因为它是受宏影响的标准库头。 如果您之前包含标头,则包含的定义将看不到宏定义。 考虑以下示例,并假设它是标准标头中包含的函数定义:

#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代替下标运算符。 即使没有调试模式,它也会诊断超出范围的访问。

任何以#…开头的内容都是对C ++预处理器的指令,该指令在实际的C / C ++编译器之前运行; 预处理程序为编译器构造最终的源代码。

所以这就是程序编译时发生的事情。

第一步:预处理

预处理程序自上而下读取您的代码并执行指令。

#define _GLIBCXX_DEBUG 1

将名为_GLIBCXX_DEBUG的标志设置为1

#include <vector>
#include <iostream>

从编译器的包含路径中读取文件vector.hiostream.h 该文件包含更多的C / C ++代码以及预处理器指令,这些指令现在以递归方式展开。 某些代码可能看起来像

#if _CLIBCXX_DEBUG
prinf("Print me to debug!");
#endif

并且此代码显示在最终的C / C ++中。 如果您的_CLIBCXX_DEBUG0则代码将不存在。 最终结果是您可以在编译之前将代码放在一起。

在您的情况下,额外的代码将特殊测试添加到最终的C / C ++文件中,这会导致您看到错误消息。 切换线路时,处理#include时不会设置该标志,因此不会将这些特殊测试添加到您的源代码中。

关于如何转储最终正在编译的最终C / C ++代码,请参见此问题

第二步:编译

一旦对C / C ++源代码文件进行了预处理(即,包含了东西,有条件地展开等等),然后将调用实际的编译器来构建代码。

有没有办法在程序的另一行切换调试模式(没有编译器标志)?

根据需要在整个代码中更改该标志的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM