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

Popular posts from this blog

android - getbluetoothservice() called with no bluetoothmanagercallback -

sql - ASP.NET SqlDataSource, like on SelectCommand -

ios - Undefined symbols for architecture armv7: "_OBJC_CLASS_$_SSZipArchive" -