2

I am setting debug mode in gcc in the following useless program:

#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];
}

and the program let's me know that my index is going out of bound. However, if I flip the ordering of the first two lines, I get no such error message (#include before #define). Why is this? Is there a way to toggle debug mode on another line in the program (without compiler flags)? I am asking because I am solving problems on Leetcode.com where I can't pass compiler flags or modify the first line of the problem.

jww
  • 97,681
  • 90
  • 411
  • 885
Hisham Hijjawi
  • 1,803
  • 2
  • 17
  • 27
  • I don't believe this is a direct dupe of https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h so I have re-opened it. But the advice in that link still applies. –  Apr 07 '19 at 00:30
  • @NeilButterworth Thank you, it definetly is not, because the issue remains the exact same if I only include iostream and vector only. – Hisham Hijjawi Apr 07 '19 at 00:31
  • Please edit your question accordingly. –  Apr 07 '19 at 00:32
  • @NeilButterworth Cm'on _`#define _GLIBCXX_DEBUG 1 #include using namespace std;`_ is probably the worst you can do. – πάντα ῥεῖ Apr 07 '19 at 00:33
  • As far as your use case goes, you can always compile and test locally before you submit, or use an online environment like Wandbox. – chris Apr 07 '19 at 00:33
  • If ``s behaviour is affected by the macro, the macro needs to be set as you need before `#include `. The macro is not a global setting - it only affects code the compiler subsequently sees. You can undefine and redefine macros using `#undef` and `#define`, or test if a macro is defined using `#ifdef`, `#ifndef`, `#if defined()`, and others. In short: read up on how to use the preprocessor BEFORE you ask for help using it. – Peter Apr 07 '19 at 01:24
  • There's another define that may be applicable for `std::vector`: [`_GLIBCXX_SANITIZE_VECTOR`](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html). – jww Jun 16 '19 at 19:43
  • These macros are originally meant to be used through command line, e.g. `-D_GLIBCXX_DEBUG`, note that they even have an underscore to make it readable with the `-D` command option. If they need to be the first line, you might as well pass it in the command line for compilation. – alfC Oct 11 '22 at 03:14

2 Answers2

5

Why does debug mode have to be set in first line?

Because it is the standard library headers which are affected by the macro. If you include the headers before, then the included definitions will not have seen the macro definition. Consider following example, and imagine that it is a function definition included from a standard header:

#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
}

versus:

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

Is there a way to toggle debug mode on another line in the program (without compiler flags)?

Not after including the standard headers.

In this case, you could use std::vector::at instead of the subscript operator. It will diagnose out of bounds access even without debug mode.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

Anything starting with a #… is an instruction to the C++ preprocessor which runs before the actual C/C++ compiler; the preprocessor constructs the final source code for the compiler.

So here is what’s happening when your program compiles.

Step one: preprocess

The preprocessor reads your code top down and executes the instructions.

#define _GLIBCXX_DEBUG 1

Set a flag called _GLIBCXX_DEBUG to 1.

#include <vector>
#include <iostream>

Read the file vector.h and iostream.h from whatever your compiler’s include path is. That file contains more C/C++ code and also preprocessor instructions which are now recursively unfolded. Some of that code may look like

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

and this code shows up in your final C/C++. If your _CLIBCXX_DEBUG is 0 then the code won’t be there. The net effect is that you can put together your code before compiling it.

In your case that extra code adds special tests into your final C/C++ file which cause the error message you see. When you switch lines, the flag won’t be set when the #include are processed, thus these special tests won’t be added into your source.

See this question on how to dump the final C/C++ code that’s actually being compiled.

Step two: compile

Once your C/C++ source code file has been preprocessed (i.e. stuff included, conditionally unfolded, etc…) then the actual compiler is invoked to build your code.

Is there a way to toggle debug mode on another line in the program (without compiler flags)?

Change the value of that flag throughout your code as you need it.

Jens
  • 8,423
  • 9
  • 58
  • 78
  • "Change the value of that flag throughout your code as you need it." Can you give me a concrete example? The answer below you says its not possible after including standard headers so i'm not sure which to believe – Hisham Hijjawi Apr 07 '19 at 00:42
  • Try adding a `#define _GLIBCXX_DEBUG 0` _after_ the two includes? However, at that point your vector definitions have already been included with debugging code enabled. – Jens Apr 07 '19 at 00:44
  • @Jens, By your own answer, that doesn't work because the preprocessor goes top-down, doing the include and then the define when it's too late. – chris Apr 07 '19 at 00:46
  • @user3586940 What are you trying to achieve? Set `_GLIBCXX_DEBUG` to `0` if you want to disable additional debug code, set it to `1` if you do want additional debug code in your program. But do that _before_ your includes… – Jens Apr 07 '19 at 00:48
  • @Jens I'm in an environment where I want to toggle debug mode, but I can't modify the compile flags or the order of inclusion of the standard headers. It seems there is no way to accomplish what I am trying to do. – Hisham Hijjawi Apr 07 '19 at 00:50
  • @user3586940, if you want to toggle debug mode at runtime, then no. If you want to toggle debug mode at compile time (i.e. hard-wire debugging code into your program or not), then you can do that my setting that preprocessor flag. – Jens Apr 07 '19 at 00:51