DI Management Home > C Programming > DPRINTF: Debug Printing in a C Program

DPRINTF: Debug Printing in a C Program


This page shows a simple way to output debugging info in an ANSI C program that can be easily turned off.

Test Code | Debug vs Release build | dprintf.h Source code | Contact us

Test Code

Just include dprintf.h in your source code (see below) and use the DPRINTF*() functions to output debugging info. This will display the debugging output in a Debug build but never display it in a Release build. There is an option to turn off the debugging output in Debug mode, too.

/* dprintf_test.c */
#include <stdio.h>
#include "dprintf.h"

int main(void) {
    int a, b;
    const unsigned char bytes[] = { 0xde, 0xad, 0xbe, 0xef, 0x01, 0x02 };
    printf("Hello world! This always prints.\n");

    DPRINTF0("Debugging DPRINTF is active...\n");
    DPRINTF1("Type=%s\n", "string");
    a = 42; b = 666;
    DPRINTF2("a=%d b=%d\n", a, b);
    DPRBYTESMSG("bytes=", bytes, sizeof(bytes));

    printf("ALL DONE.\n");
    return 0;
}
In a Debug build, this outputs all the debugging info
Hello world! This always prints.
Debugging DPRINTF is active...
Type=string
a=42 b=666
bytes=deadbeef0102
ALL DONE.
But in a Release build, all the DPRINTF statements are ignored.
Hello world! This always prints.
ALL DONE.
In fact, in release mode there is no extra penalty for these DPRINTF statements - they have no effect on the run time.

Strict argument count

The DPRINTFn() macros are strict in the number of arguments to be provided following the format string.

You must have exactly n parameters. So, for example, if you use the DPRINTF2() macro you must have exactly two parameters, i.e. in this case a and b
DPRINTF2("a=%d b=%d\n", a, b);

This is a good thing. It prevents you providing the wrong number of arguments. If you use the DPRINTF2() macro but only provide, say, one argument, you will get a compile error.

DPRINTF2("a=%d b=%d\n", a);  // Error: only one argument, need two

// warning C4003: not enough actual parameters for macro 'DPRINTF2'
Think what would happen if you use the standard printf function with the wrong number of arguments!
printf("a=%d b=%d\n", a);  // !!!

Debug vs Release build

When we say "Debug build" vs "Release build" we mean the options within Windows MSVC.

Debug build Release build

In an MSVC Debug build, the macro _DEBUG is defined.

When compiling with gcc in either Windows or Linux, we enable "Debug build" using a -D_DEBUG option.
gcc -D_DEBUG -o dprintf_test dprintf_test.c

Turn off debugging output

To turn off the debugging output in a Debug build, include the line #define NO_DPRINTF before the include statement. Comment out this line to turn it back again.

#define NO_DPRINTF  // Comment out to show debugging in DEBUG mode
#include "dprintf.h"

int main(void) {
// etc...

dprintf.h source code

Download as zip (1 kB)

/* $Id: dprintf.h  $ 
   $Date: 2025-04-05 08:51:00 $ 
   Copyright (C) 2025 David Ireland, DI Management Services Pty Limited
   <https://di-mgt.com.au/>
   @license MIT <https://opensource.org/license/mit/> 
*/

/* Debugging print macros.
   Will not show at all if in Release mode
   or if NO_DPRINTF is defined _before_ including this file
*/

#ifndef DPRINTF_H_
#define DPRINTF_H_

#if (defined(_DEBUG) && !(defined(NO_DPRINTF)))
#include <stdio.h>
#define DPRINTF0(s) printf(s)
#define DPRINTF1(s, a1) printf(s, a1)
#define DPRINTF2(s, a1, a2) printf(s, a1, a2)
#define DPRINTF3(s, a1, a2, a3) printf(s, a1, a2, a3)
#define DPRINTF4(s, a1, a2, a3, a4) printf(s, a1, a2, a3, a4)
#define DPRINTF5(s, a1, a2, a3, a4, a5) printf(s, a1, a2, a3, a4, a5)
#define DPRINTF6(s, a1, a2, a3, a4, a5, a6) printf(s, a1, a2, a3, a4, a5, a6)
#define DPRBYTES(b,n) do{int i_;for(i_=0;i_<(int)(n);i_++){printf("%02x",(b)[i_]);}printf("\n");}while(0)
#define DPRBYTESMSG(msg,b,n) do{printf("%s",(msg)); DPRBYTES((b),(n));}while(0)

#else
#define DPRINTF0(s) 
#define DPRINTF1(s, a1) 
#define DPRINTF2(s, a1, a2) 
#define DPRINTF3(s, a1, a2, a3)
#define DPRINTF4(s, a1, a2, a3, a4)
#define DPRINTF5(s, a1, a2, a3, a4, a5)
#define DPRINTF6(s, a1, a2, a3, a4, a5, a6)
#define DPRBYTES(b,n)
#define DPRBYTESMSG(msg,b,n)

#endif

#endif /* DPRINTF_H_ */

Contact us

To contact us, please send us a message. To make a comment see below.

This page first published 11 April 2025. Last updated 9 September 2025

Comments

   [Go to last comment] [Read our comments policy]
[Go to first comment]