Reputation: 848
#include <stdio.h>
#define tokenpaster(n) printf ("token" #n " = %d", token##n)
int main(void)
{
int token34 = 40;
tokenpaster(34);
return 0;
}
token34 = 40
The author says that:
How it happened, because this example results in the following actual output from the preprocessor:
printf ("token34 = %d", token34);
How token##n
is being converted into token34
? Should it not be token#34
?
Upvotes: 1
Views: 191
Reputation: 51214
A single hash prefix (#
) forces the preprocessor to stringify your argument. Double hash prefix (##
) simply pastes the argument and merges it with its prefix.
This means that tokenpaster(34)
will be expanded to:
printf ("token" "34" " = %d", token34)
^^^^ ^^
| |
| +---- pasted and merged
|
+---- enclosed in quotes
These three string literal parts are then merged into a single literal:
printf ("token34 = %d", token34)
According to the standard:
§6.10.3.2 The
#
operator2 If, in the replacement list, a parameter is immediately preceded by a
#
preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. (...)
and
§6.10.3.3 The
##
operator2 If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a
##
preprocessing token, the parameter is replaced by the corresponding argument's preprocessing token sequence (...)
Upvotes: 0
Reputation: 8053
The double-hash in a preprocessor statement glues the two arguments together. So token##n
becomes token##34
becomes token34
. A single hash stringifies its argument. So #n
becomes "34"
. And thus the whole macro-expansion is as follows:
tokenparser(34);
->
printf ("token" #n " = %d", token##n);
->
printf ("token" "34" " = %d", token##34);
->
printf ("token" "34" " = %d", token34);
and the compiler catenates the format string, so the end-result is:
printf ("token34 = %d", token34);
Upvotes: 2