Est-il possible de faire quelque chose comme ça:
#define F(x) \ #ifdef DOUBLE \ 2*x \ #else \ x \ #endif
de sorte que, lorsque j’utilise F
, l’agrandissement dépend de la définition de la macro DOUBLE
? Je ne pense pas, mais j’ai de l’espoir. Les extensions de GNU sont bien.
Edit En réponse à certaines des réponses, je l’utilise vraiment pour faire de la génération de code, où le code est légèrement différent en fonction du lieu où il est défini. En raison de l’ordre dans lequel certains fichiers sont inclus et où les macros pertinentes doivent être définies, le basculement de cette manière nécessite un peu de factorisation. Je vais peut-être devoir le faire, mais je serais ravi si je ne devais pas me peindre de ce coin!
Si nous pouvons limiter le problème, vous pouvez le faire. Plus précisément, si vous pouvez garantir que DOUBLE
est soit
#define DOUBLE
), alors vous pouvez utiliser une approche indirecte avec concaténation de jetons:
#define F_IMPL_(x) DOUBLE_IS_DEFINED #define F_IMPL_DOUBLE(x) DOUBLE_NOT_DEFINED #define F_1(x, m) F_2(x, m) #define F_2(x, m) F_IMPL_ ## m ( x ) #define F(x) F_1(x, DOUBLE)
Exemple d’utilisation:
F(t) #define DOUBLE F(t)
Résultat après prétraitement:
DOUBLE_NOT_DEFINED DOUBLE_IS_DEFINED
Cette approche fonctionnera également si DOUBLE
(s’il est défini) est défini comme une macro qui se développe en un seul jeton connu, si ce jeton peut faire partie d’un identifiant (par exemple, TRUE
ou 1
). Pour gérer cela, il vous suffit de renommer la macro F_IMPL_{TOKEN}
en F_IMPL_{TOKEN}
(par exemple, F_IMPL_TRUE
ou F_IMPL_1
).
Quel est le problème avec
#ifdef DOUBLE #define F(x) (2 * (x)) #else #define F(x) (x) #endif
Pourquoi ne pas faire la nidification dans l’autre sens?
#ifdef DOUBLE #define F(x) (2*(x)) #else #define F(x) (x) #endif
Non. La chose la plus proche que vous puissiez faire est de placer cela dans un fichier d’en-tête et #include ce fichier d’en-tête chaque fois que les définitions qui vous intéressent changent. Ceci est parfois appelé le motif “X”, parce que X
est utilisé comme une macro qui modifie la définition.
Par exemple, une utilisation courante de ce modèle est de générer automatiquement les noms de chaîne des valeurs enum:
// File myenum_values.h // NOTE: _no_ header guards so we can include this file multiple times X(Apple) X(Orange) X(banana) // File myenum.h enum Fruit { #define X(x) x, #include "myenum_values.h" } const char *FruitNames[] = { #undef X #define X(x) #x, #include "myenum_values.h" }; // We now have an array of fruit names without having to define the enum twice