2

My program used many #ifdef _DEBUG_ ... #endif blocks, to nullify the debugging functions for the release build.

However, it clogs the codes, and makes the codes unpleasant to read.

Is there any better way?

One way I can think of is to nullify it by define the function to empty, such as:

#ifdef _DEBUG_
void foo(int bar)
{
   do_somthing();
}
#else
#define foo(a) do {; } while(0)
#endif

So that we have only one #ifdef _DEBUG_ ... #endif. All the places where foo() is called, we don't have to add #ifdef _DEBUG_ ... #endif.

However, there are exceptions:

  1. When a debug function has a return value, the above strategy will not work. e.g. the codes calling the function may be in this pattern: bar = foo();
  2. When a debug function is in the form of a member function of a class, again, the above said strategy will not work.

Any idea?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Robin Hsu
  • 4,164
  • 3
  • 20
  • 37
  • See this: http://stackoverflow.com/questions/14251038/debug-macros-in-c - and in the GNU C Library, `assert()` is implemented as a macro which becomes a noop when `NDEBUG` is defined. You could look at that code for a reasonably well-tested, portable solution to at least part of the issue. – notmyfriend Nov 13 '15 at 02:53
  • See also [C `#define` macros for debug printing](https://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing) which largely applies to C++, though the suggestions can also be modified to make use of C++ features if desired. – Jonathan Leffler Nov 13 '15 at 04:41

2 Answers2

3

How about moving the #ifdef's into the function itself? i.e.

// In a .h file somewhere...
inline int foo(int bar)
{
#ifdef DEBUG
    return do_something();
#else
    (void) bar;  // this is only here to prevent a compiler warning
    return 1;  // or whatever trivial value should be returned when not debugging
#endif
}

... as long as the function can be inlined (i.e. as long as the function body is in a header file), the compiler will optimize it all away in the non-DEBUG case, so there shouldn't be any additional overhead in the non-debug build from doing it this way.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
0

If the function is too big to inline normally, Jeremy's solution won't work and you'd still need the two definitions.

// In .h file
#ifndef NDEBUG
int foo(int bar); // Definition in .cpp file
#else
inline int foo(int) {
    return 42;
}
#endif

Note that by assert convention, NDEBUG is defined for release builds.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • If the inlined function is too large, it's probably cleaner to just make a non-inlined helper function and have the inlined function call through to that as necessary. – Jeremy Friesner Nov 14 '15 at 01:34