Question

Par exemple, les possibilités suivantes sont-elles possibles:

#define definer(x) #define #x?
Était-ce utile?

La solution

Bien que votre syntaxe ne soit pas valide, la réponse à votre question est techniquement oui. Mais cela ne peut être accompli que par de mauvais trucs qui rendent votre code illisible et incontrôlable.

Voir aussi: http://www.ioccc.org/years.html#1995_vanschnitz et http://www.ioccc.org/years.html#2004_vik2

Autres conseils

Non, vous ne pouvez pas faire ça.
Le symbole dièse (#) a une signification différente dans une définition. cela signifie - s'il s'agit d'un argument, faites-en une chaîne en le citant.

Vous ne pouvez pas imbriquer les directives du préprocesseur C. Heureusement, ce n'est presque jamais nécessaire. Si vous avez vraiment besoin de ce genre de pouvoir, vous serez certainement mieux loti avec un autre pré-processeur que vous exécutez avant de transmettre le code au compilateur C. Par exemple:

sed 's/@CUSTOMER@/J. Random Person/' foo.c.in > foo.c
cc foo.c

Une autre astuce utile consiste à isoler la supercherie dans un fichier d’en-tête unique, généré par un programme que vous écrivez vous-même:

./generate-trickery --greet 'J. Random Person' > foo.h

où foo.h ressemblera à quelque chose comme ceci:

#define GREET(x) ("J. Random Person greets you, " #x)

Si vous associez cela à un Makefile ou à une autre automatisation, ce sera assez homogène et ne déclenche pas beaucoup votre développement.

Non, vous ne pouvez pas faire ça.

Vous pouvez référencer une macro par une autre, mais vous ne pouvez pas définir une macro par une autre.

Si vous essayez de créer un segment de code de préprocesseur pouvant être appelé plusieurs fois pour effectuer des opérations légèrement différentes, vous pouvez le faire (moyennement mal) en isolant le code dans un seul fichier .h que vous puis #include plusieurs fois. L'idée est que chaque fois que vous #define le fichier, vous & Appelez votre routine & Quot; - vous " passez les arguments " en commençant par ENUMVAL() inclure certaines constantes de préprocesseur auxquelles le fichier inclus fait référence.

Un endroit où j'ai vu cela être utile est de générer & "smart &"; énumérations qui peuvent convertir vers / à partir de leur " chaîne de caractères " formulaires (ce qui est utile pour les E / S). Vous créez un enum fichier contenant, par exemple,

.
ENUMVAL(foo)
ENUMVAL(bar)
ENUMVAL(baz)

puis plus tard <=> deux fois ce fichier: une fois où <=> est défini de manière à créer une déclaration <=>, et une fois lorsque <=> est défini de manière à produire un tableau des noms stringisés. En procédant ainsi, vous n'avez pas besoin de spécifier la liste des jetons réels plus d'une fois.

#define definer(x) #define #x?

#x est une chaîne de caractères de x. Vous ne pouvez pas #définir un jeton de chaîne. (#define & "; foo &";). Il doit s'agir d'un identificateur [a-zA-Z0-9 _] * .

Vous ne pouvez pas imbriquer # est comme ça. Vous ne pouvez pas avoir de #define dans un #define.

Vous pouvez avoir # si est à l'intérieur de #if blocs.

#ifdef FOO

#ifdef BAR
 ...
#else // BAR
 ...
#endif // BAR

#else // FOO
 ...
#endif //FOO

Vous êtes également quelque peu limité quant aux expressions que vous pouvez utiliser dans les macros #if. Mais vous pouvez parfois contourner ce problème. Par exemple:

        /* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4(      a,b,c,d)  CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d)  a ## b ## c ## d

    /* Creates a typedef that's legal/illegal depending on EXPRESSION.       *
     * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*".              *
     * (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT)                     \
  typedef char CONCATENATE_4( static_assert____,      IDENTIFIER_TEXT,  \
                              ____failed_at_line____, __LINE__ )        \
            [ (EXPRESSION) ? 1 : -1 ]

Plus quelque chose comme:

STATIC_ASSERT( sizeof(int1) == 1, sizeof_int1_equal_1 );

(Oui, je sais à propos de #include < stdint.h > . Ce n'est qu'un exemple.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top