JasonGenX
JasonGenX

Reputation: 5434

C++ Macro riddle: Printing the name of the TYPE

In a macro I can use xxxx_##TYPE and ##TYPE##_xxxxx to have the TYPE name filled in correctly, but I can't use ##TYPE## in the middle of a string e.g. (print "##TYPE## is the name of the type";)

Is there a way around it?

Upvotes: 5

Views: 3261

Answers (3)

ruakh
ruakh

Reputation: 183361

You can do this by combining two features. One is ''stringification'', whereby a macro argument is converted to a string by prefixing it with #. (This is related to, but different from, the ''token-pasting'' operator ## that you're obviously already familiar with.) The other is the fact that C++, when given multiple string literals in a row, will combine them into a single string. For example, "a" "b" "c" is equivalent to "abc". I'm not clear on exactly how your macro is to be defined, so I can't show you exactly what to type, but a full explanation and some good working examples are at http://gcc.gnu.org/onlinedocs/cpp/Stringification.html.


Edited to add a simple example, at Kleist's request. This program:

#include <stdio.h>

#define PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(TYPE) \
  printf("%s\n", "'" #TYPE "' is the name of the type.")

int main()
{
  PRINT_WHAT_THE_NAME_OF_THE_TYPE_IS(Mr. John Q. Type);

  return 0;
}

will print this:

'Mr. John Q. Type' is the name of the type.

(This will run in either C or C++. The reason I wrote it C-ishly is that in my experience these sorts of preprocessor tricks are more common in C code than in real C++ code; but if you wanted to use std::cout << instead of printf, you absolutely could.)

Upvotes: 7

Tom Kerr
Tom Kerr

Reputation: 10720

String literals will be concatenated when they are next to each other.

#define QUOTE(X) #X

#define DOSTUFF(TYPE) \
    void print_ ## TYPE () { \
        static const char *str = QUOTE(TYPE) " is the name of the type\n"; \
        printf(str); \
    }

DOSTUFF(Foo);

int main(int argc, char ** argv) {
    print_Foo();
    return 0;
} 

Output of g++ -E -c main.cpp will show you what this gets preprocessed into.

# 16 "main.cpp"
void print_Foo () { 
  static const char *str = "Foo" " is the name of the type\n"; 
  printf(str); 
};

int main(int argc, char ** argv) {
 print_Foo();
 return 0;
}

Upvotes: 0

Mark Ransom
Mark Ransom

Reputation: 308206

## is the token pasting operator and it takes two different tokens and pastes them together to make a single token. The entire string literal is considered a single token, thus the pasting operator doesn't work within it. See http://gcc.gnu.org/onlinedocs/gcc-4.0.4/cpp/Tokenization.html

Upvotes: 1

Related Questions