Zweifache macro expansion wird ignoriert
-
Hi
#define funcgen(name) \ func_##name #define mod d void funcgen(mod)(void) { } #undef mod int main() { func_d(); }
Statt void void func_d(void) bekomme ich von dem macro ein void func_mod(void). Ersetze ich funcgen(mod) mit funcgen(d) bekomme ich das gewünschte Ergebnis. Wenn da aber mod steht und die Zeile drüber mod auf d defined wird, wirds ignoriert
Danke!
-
Das ist ein Klassiker.
§6.10.3.3/3 schrieb:
For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a
##
preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token.Jedoch werden Argumente die nicht ein Operand von
##
sind, e.g. solche die an ein weiteres Funktionsmakro weitergeleitet werden, ersetzt:§6.10.3.1/1 schrieb:
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.I.e. folgendes funktioniert:
#define concat(a,b) a##b #define funcgen(name) concat(func_, name) #define mod d void funcgen(mod)(void) { } #undef mod int main() { func_d(); }
Demo. Boost stellt ein solches Makro im Übrigen bereits in Preprocessor zur Verfügung:
BOOST_PP_CAT
.~Edit: Huch, da dachte ich schon fast wir hätten Markdown hier im Forum :D~
-
Krass. Danke dir!