ConcatenationTheCPreprocessor
Next:VariadicMacros,Previous:Stringification,Up:Macros
3.5Concatenation
Itisoftenusefultomergetwotokensintoonewhileexpandingmacros.Thisiscalledtokenpastingortoken
concatenation.The##preprocessingoperatorperformstokenpasting.Whenamacroisexpanded,thetwo
tokensoneithersideofeach##operatorarecombinedintoasingletoken,whichthenreplacesthe##andthe
twooriginaltokensinthemacroexpansion.Usuallybothwillbeidentifiers,oronewillbeanidentifierandthe
otherapreprocessingnumber.Whenpasted,theymakealongeridentifier.Thisisn'ttheonlyvalidcase.Itis
alsopossibletoconcatenatetwonumbers(oranumberandaname,suchas1.5ande3)intoanumber.Also,
multicharacteroperatorssuchas+=canbeformedbytokenpasting.
However,twotokensthatdon'ttogetherformavalidtokencannotbepastedtogether.Forexample,youcannot
concatenatexwith+ineitherorder.Ifyoutry,thepreprocessorissuesawarningandemitsthetwotokens.
Whetheritputswhitespacebetweenthetokensisundefined.Itiscommontofindunnecessaryusesof##in
complexmacros.Ifyougetthiswarning,itislikelythatyoucansimplyremovethe##.
Boththetokenscombinedby##couldcomefromthemacrobody,butyoucouldjustaswellwritethemasone
tokeninthefirstplace.Tokenpastingismostusefulwhenoneorbothofthetokenscomesfromamacro
argument.Ifeitherofthetokensnexttoan##isaparametername,itisreplacedbyitsactualargumentbefore
##executes.Aswithstringification,theactualargumentisnotmacroexpandedfirst.Iftheargumentisempty,
that##hasnoeffect.
KeepinmindthattheCpreprocessorconvertscommentstowhitespacebeforemacrosareevenconsidered.
Therefore,youcannotcreateacommentbyconcatenating/and*.Youcanputasmuchwhitespacebetween
##anditsoperandsasyoulike,includingcomments,andyoucanputcommentsinargumentsthatwillbe
concatenated.However,itisanerrorif##appearsateitherendofamacrobody.
ConsideraCprogramthatinterpretsnamedcommands.Thereprobablyneedstobeatableofcommands,
perhapsanarrayofstructuresdeclaredasfollows:
structcommand
{
char*name;
void(*function)(void);
};
structcommandcommands[]=
{
{"quit",quit_command},
{"help",help_command},
...
};
Itwouldbecleanernottohavetogiveeachcommandnametwice,onceinthestringconstantandonceinthe
functionname.Amacrowhichtakesthenameofacommandasanargumentcanmakethisunnecessary.The
stringconstantcanbecreatedwithstringification,andthefunctionnamebyconcatenatingtheargumentwith
_command.Hereishowitisdone:
#defineCOMMAND(NAME){#NAME,NAME##_command}
structcommandcommands[]=
{
COMMAND(quit),
COMMAND(help),
https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html
1/2
12/3/2016
ConcatenationTheCPreprocessor
...
};
https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html
2/2