0

Hello could anyone explain to me what is the point in using define DEBUG, NDEBUG... and can provide me with an example. any idea idea, help, suggetion is appreciated.

so what is the point in: #define DEBUG or #define NDEBUG

kichik
  • 33,220
  • 7
  • 94
  • 114
ProDev7
  • 75
  • 7

1 Answers1

1

These preprocessor definitions are usually inserted by the compiler in debug build, for you to utilize it. For example, you may want to print debug statements only in debug build, and not to include them in release build. You can achieve that by using preprocessor:

 #ifdef _DEBUG
     printf("Debug statement here, or other piece of code");
 #endif

This printf statement will only be included in debug build.

See this question about differences between these two.

More explanation: Before cpp file actually compiler, it is passed to a program which is named preprocessor. Its task is to prepare file for compiling by, for example, replacing #include directives with the appropriate file's content, to replace macros in the code, and so on.

One of the things preprocessor is capable to do is to decide will it or will it not include blocks of code wrapped between #if(def) #else #endif# blocks (please note - this is not if/else C++ statement - these are preprocessor directives.

Let's say that, for example, you have a program which have a lot of debugging output to do:

int foo()
{
    cout << "Before doing something" << endl;
    do_something();
    cout << "After doing something" << endl;
}

Now, you don't want these prints to appear in the production executable. First is that you may go and comment all these lines manually. Second approach is that you can rely on preprocessor to do this automatically for you:

#define PRODUCTION_BUILD

int foo()
{
    #ifndef PRODUCTION_BUILD
        cout << "Before doing something" << endl;
    #endif

    do_something();

    #ifndef PRODUCTION_BUILD
        cout << "After doing something" << endl;
    #endif
}

Note: #ifndef stands for "if not defined".

Now, in your debug build, you can just remove #define PRODUCTION_BUILD and the appropriate lines will be included to the file which will be passed to the compiler. In the production build you just need to leave this define, and couts will not be included in the final exe.

Now, there is a bunch of predefined symbols that compilers can generate. One could be your Windows version, and one could be if you are compiling your code with debugging symbols or not (Debug vs Release version). This symbol is named _DEBUG (or NDEBUG, please see the link I left you).

Now your code could be just simple as this:

int foo()
{
    #ifdef _DEBUG
        cout << "Before doing something" << endl;
    #endif

    do_something();

    #ifdef _DEBUG
        cout << "After doing something" << endl;
    #endif
}

Note: We are now using #ifdef and not #ifndef.

Now your couts will be automatically included only in Debug version (we don't have to #define symbols by ourselves).

Note: This is only for presentation purposes. You don't want to put #ifdefs in every few lines, but you may want, for example to provide a function which will won't do anything in the Release build (will have empty body), and it could do logging in Debug version.

Community
  • 1
  • 1
Nemanja Boric
  • 21,627
  • 6
  • 67
  • 91