13

I write the following macro for debug convinience,

1 #ifndef DEF_H
2 #define DEF_H
3 #define DEBUG_MODE
4 #define DEBUG_INFO(message)     \
5         #ifdef DEBUG_MODE       \
6                 cout << message << endl; \
7         #endif                          \
8 #endif

but gcc complains as the following

def.h:4: error: '#' is not followed by a macro parameter
def.h:1: error: unterminated #ifndef

What's wrong with this piece of code? Do I miss some important points here?

a3f
  • 8,517
  • 1
  • 41
  • 46
speedmancs
  • 339
  • 2
  • 4
  • 12

3 Answers3

25

You cannot have #ifdefs inside a macro definition. You need to turn it inside out:

#ifdef DEBUG_MODE
#define DEBUG_INFO(message) cout << (message) << endl
#else
#define DEBUG_INFO(message)
#endif
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Thank you. So how can I achieve the goal using macro to control the debug switch. In the client end, I prefer to call just a single line like DEBUG_INFO("debug info") – speedmancs Apr 09 '12 at 14:18
  • +1. Also, there is a backslash after line 7, which causes the #endif in the last line to be part of line 4, and not match the #ifndef in the first line – Mr Lister Apr 09 '12 at 14:20
3

You can't embed a preprocessor directive in another preprocessor directive (the #ifdef DEBUG_MODE inside the definition of DEBUG_INFO). Instead, do something like

#ifdef DEBUG_MODE
# define DEBUG_INFO(message) cout << message << endl
#else
# define DEBUG_INFO(message) 0
#endif

(This is still not ideal; defensive macro coding suggests something like

#ifdef DEBUG_MODE
# define DEBUG_INFO(message) do {cout << message << endl;} while (0)
#else
# define DEBUG_INFO(message) 0
#endif

Perhaps an inline function would work better.)

geekosaur
  • 59,309
  • 11
  • 123
  • 114
  • 1
    "You can't embed a preprocessor directive in another preprocessor directive ", this is not true for all cases, is it ? e.g. #if, #ifdef and #ifndef – Zoso May 24 '18 at 15:02
0

I geuss if you eat '\' at line 7, the piece of Code will work.

Kevin
  • 11
  • 2