1

From what I understand assert is a macro in C and supposedly if you use it at compile time but leave it disabled then there won't be overhead (which might not be correct I don't know). The problem for me is that what I'd like to do is get all the variables passed to my function and print out that output, but only if I want debugging enabled. Here is what I have so far:

int exampleFunction (int a, int b)
{
  #ifdef debugmode
  printf("a = %i, b = %i", a, b);
  #endif 
}

I'm wondering if there is any easier (and less ugly) method for doing something like this. xdebug for php has this feature and I've found is saves me an enormous amount of time when debugging so i want to do it for each function.

Thanks

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
Matthew Stopa
  • 3,793
  • 6
  • 42
  • 51
  • 1
    The assert() macro is disabled entirely if NDEBUG is defined, so if that is defined in release mode there will be no overhead. – David Thornley Jun 17 '09 at 19:17

7 Answers7

11

try this:

#ifdef debugmode
#define DEBUG(cmd) cmd
#else
#define DEBUG(cmd)
#endif


DEBUG(printf("a = %i, b = %i", a, b));

now, if you have debugmode defined, you get your print statement. otherwise, it never shows up in the binary.

eduffy
  • 39,140
  • 13
  • 95
  • 92
  • Sadly you're left with a useless function call in its place but I +1 this in my struggle to be less of a purist. – Kai Jun 17 '09 at 18:57
  • Hmm this left me with a compiler error of: `b' undeclared (first use this function) Not sure why – Matthew Stopa Jun 17 '09 at 19:01
  • 3
    @Kai - There is no useless function call when debugmode is undefined. The preprocessor replaces the printf with just a semicolon, that then gets translated to nothing in the executable. – eduffy Jun 17 '09 at 19:04
  • 1
    This should work with any C90 implementation, which puts it ahead of some of the solutions that only work with C99 functionality. – David Thornley Jun 17 '09 at 19:18
  • The non-debug version of the macro should ensure that the compiler validates the debug code. For example, the #else clause might be: #define DEBUG(cmd) do { if (0) cmd; } while (0) -- the compiler validates the command, but then optimizes it away (and if it doesn't optimize it away, you've got bigger problems than this - get a new compiler). – Jonathan Leffler Jun 18 '09 at 00:47
3

Using GCC, I really enjoy to add, per file:

#if 0
#define TRACE(pattern,args...)   fprintf(stderr,"%s:%s/%u" pattern "\n",__FILE__,__FUNCTION__,__LINE__,##args)
#else
#define TRACE(dummy,args...)
#endif

and then in the code:

i++;
TRACE("i=%d",i);

i will be printed only when I activate the TRACE() macro in the top of the file. Works really great, plus it prints the source file, line and function it occurred.

0x6adb015
  • 7,473
  • 4
  • 24
  • 38
1
if (MY_DEBUG_DEFINE) {
        do_debug_stuff();
}

Any half decent compiler would optimize the block away. Note you need to define MY_DEBUG_DEFINE as a boolean (ie 0 or not 0).

#define MY_DEBUG_DEFINE defined(NDEBUG)

If you happen to compile with maximum warning level, this trick avoids unreferenced argument.

diapir
  • 2,872
  • 1
  • 19
  • 26
1

Workaround to get vararg with preprocessors that don't support it

#define DEBUG

#ifdef DEBUG
#define trace(args) printf args
#else
#define trace(args)
#endif


int dostuff(int value)
{


    trace(("%d", value));

}
Joakim Elofsson
  • 36,326
  • 1
  • 22
  • 28
0

You can define PRINTF_IF_DEBUGGING as

#ifndef NDEBUG
#define PRINTF_IF_DEBUGGING(X) printf(X)
#else
#define PRINTF_IF_DEBUGGING(X)
#endif

This will centralize the #ifdefs in only one place.

florin
  • 13,986
  • 6
  • 46
  • 47
0

Well, the problem with the PRINT_DEBUG type macros as given here, is that they only allow one parameter. For a proper printf() we'll need several, but C macros don't (presently) allow variable arguments.

So, to pull this off, we've got to get creative.

#ifdef debugmode
     #define PRINTF   printf
#else
     #define PRINTF    1 ? NULL : printf
#endif

Then when you write PRINTF("a = %i, b = %i", a, b);, in non-debug mode, it will be renders as (effectively):

 if (true) NULL;
 else printf("a = %i, b = %i", a, b);

The compiler is happy, but the printf is never execute, and if the compiler if bright (i.e, any modern C compiler), the code for the printf() will never be generated, as the compiler will recognize that path can never be taken.

Note, however, that the parameters will still be evaluated, so if they have any side effects (i.e, ++x or a function call), they code may be generated (but not executed)

James Curran
  • 101,701
  • 37
  • 181
  • 258
0

I would also print some other C preprocessor flags that can help you track problems down

printf("%s:%d {a=%i, b=%i}\n", __FILE__, __LINE__, a, b);
Pete
  • 10,310
  • 7
  • 53
  • 59