1

I want to create a macro that prints some info and takes any number of arguments to print additional message(s) if needed.

Here's a code snippet im talking about:

#include <stdio.h>

#define print(msg, ...) \
    printf("Line: %d File %s "## msg, __LINE__ , __FILE__, __VA_ARGS__);

int main()
{
    print("Msg: %d", 13);
    print("Msg: %d, Msg2: %d", 123, 234);
}

Here's an error I'm getting:

main.cpp:12:9: error: pasting ""Line: %d File %s "" and ""Msg: %d"" does not give a valid preprocessing token
  printf("Line: %d File %s "## msg, __LINE__ , __FILE__, __VA_ARGS__);

What am I doing wrong?

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
flamasterrr
  • 269
  • 3
  • 12
  • 1
    Why are you writing C code and pretending it's C++? – paxdiablo Jul 18 '18 at 11:41
  • @paxdiablo the name of the file is main.cpp, so I think it is C style C++ code. – mch Jul 18 '18 at 11:42
  • @mch: yes, hence the "pretend" clause in my comment :-) C-style C++ code, as you eloquently put it, is possibly the *worst* thing you can do to learn C++. Having said that, the fact that it is `main.cpp` *does* indicate C++, so I'll restore the C++ tag (and take away the C one) - it's very rare that a question should have both. – paxdiablo Jul 18 '18 at 11:43

2 Answers2

2

C string literals are joined automatically. The ## you have now is meant to join two "tokens" (not strings) into one, e.g. to take ABC and XYZ and make ABCXYZ as an identifier.

You want this:

printf("Line: %d File %s " msg, __LINE__ , __FILE__, __VA_ARGS__);
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
2

Exactly what it says on the tin: "Line: %d File %s ""Msg: %d" is not a single, valid preprocessing token as ## is required to produce.

Just drop the ##, as adjacent string literals are already concatenated by the preprocessor.

Quentin
  • 62,093
  • 7
  • 131
  • 191