c++ - Macro concatenation using compiler define -
this should simple, i'm struggling figure out. have project_name
compiler (g++
) -d
define, , want concatenate other text form namespace name. current approach this:
#define version_namespace project_name ## versioning
for current project, expect version_namespace
syren_dllversioning
. instead compiler error:
error: 'project_nameversioning' has not been declared
but according g++
call, project_name
being defined properly:
ccache g++ ... -dproject_name=syren_dll ...
why project_name
not being replaced before concatenation takes place?
a macro name not expanded when appears next ##
operator, need more layers of indirection:
#define p_version2(foo) foo ## versioning #define p_version(foo) p_version2(foo) #define version_namespace p_version(project_name)
so project_name
expanded argument of p_version
, concatenated in p_version2
.
in section 16.3.3 [cpp.concat], paragraph 3, specified
for both object-like , function-like macro invocations, before replacement list reexamined more macro names replace, each instance of
##
preprocessing token in replacement list (not argument) deleted , preceding preprocessing token concatenated following preprocessing token.
that preprocessing tokens adjacent ##
preprocessing token concatenated before macro-replacement done on replacement list. therefore, project_name
must passed through (function-like) macro replaced , concatenated versioning
.
but in 16.3.1 [cpp.subst], paragraph 1, standard specifies (emphasis added me)
after arguments invocation of function-like macro have been identified, argument substitution takes place. parameter in replacement list, unless preceded
#
or##
preprocessing token or followed##
preprocessing token (see below), replaced corresponding argument after macros contained therein have been expanded. before being substituted, each argument’s preprocessing tokens macro replaced if formed rest of preprocessing file; no other preprocessing tokens available.
that macro parameters not subject further macro-expansion if adjacent ##
preprocessing token. therefore, function-like macro receives project_name
argument must not directly concatenate argument versioning
, expand project_name
must call function-like macro concatenation.
so in above, invocation ccache g++ ... -dproject_name=syren_dll ...
, project_name
replaced syren_dll
when p_version(project_name)
expanded, resulting in p_version2(syren_dll)
leads concatenation of syren_dll
, versioning
.
Comments
Post a Comment