0

I have two C macros, the first one is basically concatenating two tokens

#define _PY_CLASS_NAME(name) Py##name

The second macro is stringifying input argument

#define STR(text) #text

Because of the way C preprocessor work when I try something like

STR(_PY_CLASS_NAME(name))

I actually get "_PY_CLASS_NAME(name)". So the question is, how to avoid it?

I tried something like

#define CONCAT(A, B) #A###B

and it works. But maybe it is a better way to do it?

  • Note that you should not create names that start with an underscore followed by either another underscore or a capital letter. Such names are 'reserved for any use' by the implementation. See [C11 §7.1.3 Reserved identifiers](http://port70.net/~nsz/c/c11/n1570.html#7.1.3). – Jonathan Leffler Dec 29 '17 at 07:40
  • In the `#define CONCAT(A, B) #A###B` example, the preprocessor is entitled to complain that the `##` operator is not joining two identifiers. The 'maximal munch' rule means that you have `#A ## #B` and `#B` is not an identifier. You certainly shouldn't try using it. – Jonathan Leffler Dec 29 '17 at 07:43
  • See also [How to concatenate twice with the C preprocessor and expand a macro as in `arg ## _ ## MACRO`?](https://stackoverflow.com/questions/1489932/) and [How to make a char string from a C macro's value?](https://stackoverflow.com/questions/195975/) – Jonathan Leffler Dec 29 '17 at 07:49
  • @JonathanLeffler.: Second won't work no matter what. – user2736738 Dec 29 '17 at 07:52

1 Answers1

1
#define _PY_CLASS_NAME(name) Py##name
#define STR(a) STR_(a)
#define STR_(a) #a

This solves the problem in a different way and also would clarify how it macro works. Reason is - when macro arguments are substituted in the macro body, they are expanded until they appear with the # or ## pre-processor operators in that macro.

Now doing this printf("%s\n",STR(_PY_CLASS_NAME(name))); prints Pyname.

Edit: The second one you mentioned won't work. The compiler complains as mentioned, of absence of valid preprocessing token.

user2736738
  • 30,591
  • 5
  • 42
  • 56