C ++ Macro riddle: printing a TYPE name

In a macro, I can use xxxx _ ## TYPE and ## TYPE ## _ xxxxx to properly fill in the TYPE name, but I cannot use ## TYPE ## in the middle of the line, for example. (print "## TYPE ## is the type name";)

Is there any way?

+4
source share
3 answers

You can do this by combining two functions. One of them is the "structure", as a result of which the macro is converted to a string by prefixing it with # . (This is related to, but different from the `` token-pasting '' ## operator, which you are obviously already familiar with.) Another fact is that C ++, when specifying multiple string literals in a string, will combine them into one line. For example, "a" "b" "c" equivalent to "abc" . I don’t quite understand how exactly your macro should be defined, so I can’t show you what exactly to type, but a full explanation and some good working examples can be found at http://gcc.gnu.org/onlinedocs/cpp/Stringification. html


Edited to add a simple example, as requested by Kleist. 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 work either in C or C ++. The reason I wrote C-ishly is because, in my experience, these kinds of preprocessing tricks are more common in C code than in real C ++ code, but if you want to use std::cout << instead of printf , you absolutely could.)

+6
source

## is a token gluing operator , and it takes two different tokens and puts them together to make one token. The entire string literal is considered the only token, so the insert statement does not work inside it. See http://gcc.gnu.org/onlinedocs/gcc-4.0.4/cpp/Tokenization.html

+1
source

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; } 

The output of g++ -E -c main.cpp will show you what the preprocessor is.

 # 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; } 
0
source

Source: https://habr.com/ru/post/1383985/


All Articles