At: C++ FAQ - Miscellaneous technical issues - [39.6] What should be done with macros that need to paste two tokens together?
Could someone explain to me wh
The relevant part of the C spec:
6.10.3.1 Argument substitution
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.
The key part that determines whether you want the double indirection or not is the second sentence and the exception in it -- if the parameter is involved in a #
or ##
operation (such as the params in mymacro
and NAME2_HIDDEN
), then any other macros in the argument are NOT expanded prior to doing the #
or ##
. If, on the other hand, there's no #
or ##
IMMEDIATELY in the macro body (as with NAME2
), then other macros in the parameters ARE expanded.
So it comes down to what you want -- sometimes you want all macros expanded FIRST, and then do the #
or ##
(in which case you want the double layer indirection) and sometime you DO NOT want the macros expanded first (in which case you CAN'T HAVE double layer macros, you need to do it directly.)
The most non-technical answer, which I gathered from all links here, and link of links ;) is that, a single layer indirection macro(x) #x
stringifies the inputted macro's name, but by using double layers, it will stringify the inputted macro's value.
#define valueOfPi 3
#define macroHlp(x) #x
#define macro(x) macroHlp(x)
#define myVarOneLayer "Apprx. value of pi = " macroHlp(valueOfPi)
#define myVarTwoLayers "Apprx. value of pi = " macro(valueOfPi)
printf(myVarOneLayer); // out: Apprx. value of pi = valueOfPi
printf(myVarOTwoLayers); // out: Apprx. value of pi = 3
What happens at printf(myVarOneLayer)
printf(myVarOneLayer)
is expanded to printf("Apprx. value of pi = " macroHlp(valueOfPi))
macroHlp(valueOfPi)
tries to stringify the input, the input itself is not evaluated. It's only purpose in life is to take an input and stringify. So it expands to "valueOfPi"
So, what happens at printf(myVarTwoLayers)
printf(myVarTwoLayers)
is expanded to printf("Apprx. value of pi = " macro(valueOfPi)
macro(valueOfPi)
has no stringification operation, i.e. there is no #x
in it's expansion, but there is an x
, so it has to evaluate x
and input the value to macroHlp
for stringification. It expands to macroHlp(3)
which in turn will stringify the number 3, since it is using #x
__LINE__
is a special macro that is supposed to resolve to the current line number. When you do a token paste with __LINE__
directly, however, it doesn't get a chance to resolve, so you end up with the token prefix__LINE__
instead of, say, prefix23
, like you would probably be expecting if you would write this code in the wild.
Chris Dodd has an excellent explanation for the first part of your question. As for the second part, about the definition sequence, the short version is that #define
directives by themselves are not evaluated at all; they are only evaluated and expanded when the symbol is found elsewhere in the file. For example:
#define A a //adds A->a to the symbol table
#define B b //adds B->b to the symbol table
int A;
#undef A //removes A->a from the symbol table
#define A B //adds A->B to the symbol table
int A;
The first int A;
becomes int a;
because that is how A
is defined at that point in the file. The second int A;
becomes int b;
after two expansions. It is first expanded to int B;
because A
is defined as B
at that point in the file. The preprocessor then recognizes that B
is a macro when it checks the symbol table. B
is then expanded to b
.
The only thing that matters is the definition of the symbol at the point of expansion, regardless of where the definition is.
The order in which macros are declared is not important, the order in which they are used is. If you were to actually use that macro before it was declared -- (in actual code that is, not in a macro which remains dormant until summoned) then you would get an error of sorts but since most sane people don't go around doing these kinds of things, writing a macro and then writing a function that uses a macro not yet defined further down, etc,etc... It seems your question isn't just one question but I'll just answer that one part. I think you should have broken this down a little more.