It helps to understand the nature of the problem. The #
symbol is special to the preprocessor in three ways:
A source line whose first preprocessing token is #
is recognized by the preprocessor as not being a "text line". That is, it contains instructions for the preprocessor. Text lines, on the other hand, are the data to be processed -- mostly C program source, but possibly containing macros to be expanded. The #
is not special in this sense if it is not the first preprocessing token on the line.
Among the preprocessing tokens of the replacement list for a function-like macro, the token #
is the stringification operator. It does not serve that purpose in a variable-like macro, however, nor when macro-expanded text is re-scanned for further macro replacement.
Among the preprocessing tokens of the replacement list for a function-like macro, the token ##
is the token-pasting operator. It does not serve that purpose in a variable-like macro, however, nor when macro-expanded text is re-scanned for further macro replacement.
You cannot escape the significance of the #
to the preprocessor per se, but you can nevertheless implement your desired macro by employing a bit of indirection, as @Quentin demonstrated. In the first place, if a #
is to appear in the expansion of a function-like macro then it cannot appear directly in that macro's replacement text, where it would be interpreted as the stringification operator. It must instead be introduced by expanding another macro. In the second place, if it must abut other text without whitespace between, then the immediate macro that expands to it must be a function-like macro itself, so that the parentheses serve to separate the macro name from the abutting text. That requires a second level of indirection.