3

I followed the online tutorial and wanted to use #undef to design my debug output function. I wrote a debugOut.h file. The content is as follows:

#include <stdio.h>

#define NOOP //(void(0))

#undef DEBUG_PRINT

#if DEBUG_OUT
#define DEBUG_PRINT printf
#else 
#define DEBUG_PRINT(...) NOOP
#endif 

#undef DEBUG_OUT

Then I wrote a main function to test whether my design is correct.

#include<iostream>
#include "Header/debug_out.h"
#define DEBUG_OUT
int main(){
    DEBUG_PRINT("module1 debug...\n");
    printf("hello,world");
}

But the output result is only hello, world. Why I defined #define DEBUG_OUT, why is DEBUG_PRINT not replaced with printf

I wrote it based on an online tutorial. I want to write an output function for c++ based on this. But in the sentence #define DEBUG_PRINT(...) NOOP, what does (...) represent? Is there any way I can output what the macro definition is replaced with?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Gerrie
  • 736
  • 3
  • 18
  • 1
    Does you compiler accept the `-E`commandline switch? – Yunnosch Nov 18 '20 at 07:07
  • 1
    At the time the header is read, `DEBUG_OUT` is not defined. Therefore you get the NOOP version of `DEBUG_PRINT`. If you want the non-debug version, make sure `DEBUG_OUT` is defined before including the header. – Jonathan Leffler Nov 18 '20 at 07:07
  • 1
    The `(...)` means it is a variadic macro - one that can accept any number of arguments. Since it doesn't do anything with the arguments, that macro definition effectively discards all its arguments. The version of that macro that expands to a call of `printf()` could have also been specified as `#define DEBUG_PRINT(...) printf(__VA_ARGS__)` which expands to a call of `printf()` that explicitly passes all arguments (no matter how many) of the macro as arguments to `printf()`. – Peter Nov 18 '20 at 07:45

2 Answers2

7

The preprocessor basically scans the input from top to bottom. So it first processes the #if DEBUG_OUT included from #include "Header/debug_out.h" and only then it processes #define DEBUG_OUT.

You need to make sure DEBUG_OUT is defined before the contents of Header/debug_out.h are processed. The following should work:

#include<iostream>
#define DEBUG_OUT             // first define DEBUG_OUT 
#include "Header/debug_out.h" // when this is processed DEBUG_OUT is defined
int main(){
    DEBUG_PRINT("module1 debug...\n");
    printf("hello,world");
}

In Addition there is a typo in "Header/debug_out.h":

#if DEBUG_OUT

should be

#ifdef DEBUG_OUT
Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • Oh, I think what you said makes sense. But after I changed it like this, the compilation went wrong. Header/debug_out.h:19:14: error: #if with no expression. But there is a statement after if. Before the change, it can be compiled normally. – Gerrie Nov 18 '20 at 07:14
  • Thanks for your answer. Do you know what the (...) in #define DEBUG_PRINT(...) NOOP means? – Gerrie Nov 18 '20 at 07:23
  • I avoid macros as far as possible :) But I think it's a variadic macro. – Lukas-T Nov 18 '20 at 10:34
2
#include <stdio.h>

#define NOOP //(void(0))

#undef DEBUG_PRINT

#if DEBUG_OUT      ///////////should be #ifdef
#define DEBUG_PRINT printf
#else 
#define DEBUG_PRINT(...) NOOP
#endif 

#undef DEBUG_OUT

below is copied from the voted most.

#include<iostream>
#define DEBUG_OUT             // first define DEBUG_OUT 
#include "Header/debug_out.h" // when this is processed DEBUG_OUT is defined
int main(){
    DEBUG_PRINT("module1 debug...\n");
    printf("hello,world");
}
road
  • 49
  • 4
  • Thanks for your answer. Do you know what the (...) in #define DEBUG_PRINT(...) NOOP means? – Gerrie Nov 18 '20 at 07:31
  • #define DEBUG_PRINT(...) NOOP will co-work with #define NOOP the result is the DEBUG_PRINT("module1 debug...\n"); will become empty statement. "..." means variadic arguments in C language – road Nov 18 '20 at 08:11