Force the compiler to ignore some lines in the program

C++Preprocessor Directive

C++ Problem Overview


Suppose that I have 10,000 lines of C++ code. 200 lines of this code are for testing purpose (for example, check the program and show an error message).

Is there an way in C++ to ignore or consider some lines of the code (maybe with preprocessor keywords)?

C++ Solutions


Solution 1 - C++

Short answer:

Use macros and #ifdef checking. For example:

#ifdef MY_CONTROL_MACRO
...
#endif

the code within this scope will only be compiled if you already defined the MY_CONTROL_MACRO macro.


More stuff:

  1. To define such a macro, you can
  • Add #define MY_CONTROL_MACRO to your code. Or,
  • For VS, add MY_CONTROL_MACRO to Project > Properties > C/C++ > Preprocessor > Preprocessor Definitions. Or,
  • For GCC, compile your code with option -DMY_CONTROL_MACRO.
  1. You can check out here for more info. > This block is called a conditional group. controlled text will be included in the output of the preprocessor if and only if MACRO is defined. We say that the conditional succeeds if MACRO is defined, fails if it is not.

> The controlled text inside of a conditional can include preprocessing directives. They are executed only if the conditional succeeds. You can nest conditional groups inside other conditional groups, but they must be completely nested. In other words, ‘#endif’ always matches the nearest ‘#ifdef’ (or ‘#ifndef’, or ‘#if’). Also, you cannot start a conditional group in one file and end it in another.

  1. You can also use the advanced ifdef-else-endif style:

     #ifdef MY_CONTROL_MACRO
     	... // this part will be valid if MY_CONTROL_MACRO is defined
     #else
     	... // this part will be valid if MY_CONTROL_MACRO is NOT defined
     #endif
    

Solution 2 - C++

Surround the code with "#ifdef...#endif", and then use the compiler options to set the flag:

#ifdef MYTEST_ONLY_FUNCTIONALITY_ENABLED
...
#endif

You can then use the compiler options to include this code. For example, in GCC:

-DMYTEST_ONLY_FUNCTIONALITY_ENABLED

Though, to be honest, I think this approach is generally not very maintainable in large projects and, if possible, it is generally better to simply move the test-only code to a completely separate library (without this conditional logic) and simply link that code into your test binary rather than your non-test binary. That also avoids having to compile each of the other libraries in both debug and non-debug modes.

Solution 3 - C++

This is what #ifdef was designed for

You put

#ifdef TESTS
... test code ...
#endif

and then you can pass to the compiler options to decide if you want the test part compiled in or not. For example with g++ it's

g++ -DTESTS ...

Solution 4 - C++

Using a preprocessor guard is definitely the most flexible and common approach. However, when possible, I suggest using an if statement. For example, instead of

void example(int a){
   int some_local;
   ...
   #ifdef _DEBUG
   std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
   #endif
   ....
}

Assuming ENABLE_DEBUG is defined to be 0 or non-zero, I would use

void example(int a){
   int some_local;
 
   ...
   if(ENABLE_DEBUG) std::cout << "In function " << __FUNCTION__ << "(" << a <<")" << std::endl;
   ...
}

Since ENABLE_DEBUG is a constant, when ENABLE_DEBUG is 0 the compiler will not generate any code for statements it guards. So, why use this method instead of #ifdef?

  1. If there are many separate debug statements spread throughout the code, it can be a bit easier to read
  2. More importantly, the code is always processed for syntactic errors, even if no code is generated. This can be very helpful if the debug code is not frequently enabled. If variables change (e.g. in the above example if the argument a was renamed), then the person making the change will know they have to update the debug statement as well. If #ifdefs are used, then it can hide bit rot until someone needs to enable the debug code and then they have to go and try and fix up the code, something that may not be obvious to them.

Obviously this approach only works for debug statements inside method/function bodies.

Solution 5 - C++

Go with the existing convention, and use the NDEBUG macro. All common compilers define this macro for release builds, and do not define it for debug builds.

The macro originally existed to control the output of assert(3), and is defined as such all the way back in the POSIX standard and at least since C89.

Note that you have to reverse the test with #ifndef.

An example:

#ifndef NDEBUG
    /* Debugging code */
    std::cerr << "So far we have seen " << unicorns << " unicorns" << std::endl;
#endif

P.S. With gcc/g++, you do a debug build by adding -g to the command line.

Solution 6 - C++

Surround your testing code #ifdef DEBUG.

#if DEBUG
   ....
#endif

Solution 7 - C++

Use preprocessor #define and #if

depending on your compiler, you should have some variables available by default i.e NDEBUG (for not-debug) or DEBUG

you can define a variable yourself in code by

#define MY_VARIABLE

and use it as follows

#ifdef MY_VARIABLE
  //code that compiles only if MY_VARIABLE is defined
  printf("test output here");
#else
  //code that compiles only if MY_VARIABLE is NOT defined
  printf("MY_VARIABLE is not defined");
#endif

for more information search online for

#define, #if, #ifdef, #ifndef

Solution 8 - C++

The way to go is using preprocessor directive with the define passed to the compiler or taken from a header "config.h":

#if defined(DEBUG) // or #ifdef DEBUG
    // Debug code
#endif

To avoid to use everywhere in source code:

#if defined(DEBUG)
    My_Debug_function(some_variable)
#endif

You may do in the header

#if !defined(DEBUG) // or #ifndef DEBUG
# define My_Debug_function(some_variable) do { static_cast<void>(some_variable); } while (false)  /* Do nothing */
#endif

And so use My_Debug_function almost normally.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1436187View Question on Stackoverflow
Solution 1 - C++herohuyongtaoView Answer on Stackoverflow
Solution 2 - C++Michael Aaron SafyanView Answer on Stackoverflow
Solution 3 - C++6502View Answer on Stackoverflow
Solution 4 - C++TheDukeView Answer on Stackoverflow
Solution 5 - C++Michael HamptonView Answer on Stackoverflow
Solution 6 - C++Richard SchneiderView Answer on Stackoverflow
Solution 7 - C++user3218782View Answer on Stackoverflow
Solution 8 - C++Jarod42View Answer on Stackoverflow