7

I have a macro I use for debugging.

#define diagnostic_arg(message,...) fprintf(stderr,message,__VA_ARGS__)

I've found that I need to use wide-chars in my program, so I would like to change just my macro and have everything work:

#define diagnostic_arg(message,...) fwprintf(stderr,message,__VA_ARGS__)

However, I need wide character strings, which are defined by putting an L in front of the string's beginning quote mark:

#define diagnostic_arg(message,...) fprintf(stderr,Lmessage,__VA_ARGS__)

Now obviously, the above line doesn't work. But if I use L message, that won't work either. So how do I write Lmessage and have it do what I would like?

Richard
  • 56,349
  • 34
  • 180
  • 251

2 Answers2

16

You can use the token pasting operator ##:

#define diagnostic_arg(message,...) fprintf(stderr,L##message,__VA_ARGS__)

However, it might be better to use TEXT macro (if you are in Visual Studio) which will do the right thing whether UNICODE is defined or not:

#define diagnostic_arg(message,...) fprintf(stderr,TEXT(message),__VA_ARGS__)

If you're not, TEXT can be defined like this:

#ifdef UNICODE
#define TEXT(str) L##str
#else
#define TEXT(str) str
#endif

However, if you plan on using other #defines as the first argument to this macro (and really even if you don't plan on it), you will need another layer of indirection in the macro so the definition will be evaluated instead of pasted together with L as text. See Mooing Duck's answer for how to do that, his is actually the correct way to do this, but I'm not deleting this answer because I want to keep my 80 rep.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
8

I vaguely recall the answer being something along the lines of

//glues two symbols together that can't be together
#define glue2(x,y) x##y
#define glue(x,y) glue2(x,y) 
//widens a string literal
#define widen(x) glue(L,x)

#define diagnostic_arg(message,...) fprintf(stderr,widen(message),__VA_ARGS__)

Glue sometimes needs to be two macros (as I've shown), for bizzare reasons I don't quite understand, explained at the C++faq

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • Of course, Seth Carnegie's answer is far more straight to the point, I don't know why the direct route didn't occur to me. – Mooing Duck Mar 21 '12 at 21:22
  • I remember something like this too, I can't remember when it's needed though. – Seth Carnegie Mar 21 '12 at 21:24
  • Ah, here it is: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 It's so you can use other `#define`s in there. This answer is actually the correct one. – Seth Carnegie Mar 21 '12 at 21:25
  • You need the extra bit of indirection in case what's passed in the `message` argument is a macro itself. – Michael Burr Mar 21 '12 at 21:28
  • I appreciate the technical correctness of this. @SethCarnegie's answer seemed to work fine in my use scenario, though. Thank you both. – Richard Mar 21 '12 at 21:29