97 votes

Macros préprocesseur multi-lignes

Comment faire une macro préprocesseur multi-lignes ? Je sais comment faire une ligne :

#define sqr(X) (X*X)

mais j'ai besoin de quelque chose comme ça :

#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };

Comment faire pour que ça marche ?

Il ne s'agit que d'un exemple, la macro réelle peut être très longue.

0 votes

Vous pouvez facilement obtenir la réponse en faisant une recherche sur l'OS. Par exemple stackoverflow.com/questions/4007865/

0 votes

Différentes méthodes sont ici : parashift.com/c++-faq/macros-avec-multi-stmts.html

0 votes

146voto

Ed S. Points 70246

Vous utilisez \ comme caractère d'échappement pour la continuation de la ligne.

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }

EDIT : Comme @abelenky l'a fait remarquer dans les commentaires, les \ caractère doit être le dernier caractère de la ligne . Si ce n'est pas le cas (même si ce n'est qu'un espace blanc après), vous obtiendrez des messages d'erreur déroutants sur chaque ligne qui suit.

51 votes

Un mot d'avertissement : Assurez-vous que le \N est le dernier personnage sur la ligne. En C, les espaces blancs n'ont généralement pas d'importance, mais dans ce cas, les espaces blancs invisibles en fin de ligne peuvent vous tuer.

2 votes

Il faut cependant ajouter que le texte résultant est sur une seule ligne. Comme C traite tous les espaces blancs entre les tokens de la même manière, cela n'a généralement pas beaucoup d'importance, mais quand même.

0 votes

Une autre chose que je suggérerais de faire est de placer ` after all useful lines of the macro, and add a comment afterward saying something like // Ligne vierge nécessaire après la macro . It's sometimes easier to ensure that all lines of a macro end with ` que de s'assurer que tout sauf la dernière ligne le fait.

22voto

Kerrek SB Points 194696

Vous pouvez faire en sorte qu'une macro couvre plusieurs lignes en mettant une barre oblique inverse ( \ ) à la fin de chaque ligne :

#define F(x) (x)   \
              *    \
             (x)

20voto

jnbbender Points 391

VEUILLEZ NOTER comme l'ont souligné Kerrek SB et coaddict, ce qui aurait dû être signalé dans la réponse acceptée, TOUJOURS placez des accolades autour de vos arguments. L'exemple sqr est l'exemple simple enseigné dans les cours de CompSci.

Voici le problème : si vous le définissez comme vous l'avez fait, que se passe-t-il lorsque vous dites " sqr(1+5) " ? Vous obtenez "1+5*1+5" ou 11.
Si vous placez correctement un appareil dentaire autour, **#define** sqr(x) ((x)*(x))
vous obtenez ((1+5) * (1+5)) ou ce que nous voulions 36 ...beau.

Ed S. va avoir le même problème avec "swap".

6voto

codaddict Points 154968

Vous devez échapper à la nouvelle ligne à la fin de la ligne en l'échappant avec un caractère de type \ :

#define sqr(X) \
        ((X)*(X))

3voto

sifferman Points 2137

Bien que cela ne fasse pas partie de la question initiale, aucune des autres réponses ne mentionne que les commentaires intégrés dans des macros multi-lignes nécessitent une attention particulière.

  • Les commentaires de style C++ ne peuvent pas apparaître sur une ligne comportant un caractère d'échappement de continuation de ligne.
  • Les commentaires de style C ne peuvent pas s'étendre sur plusieurs lignes séparées par un caractère d'échappement de continuation de ligne.

Exemples :

// WRONG:
#define someMacro(X)          \
// This comment is a problem. \
class X : public otherClass   \
{                             \
     int foo;                 \
     void doFoo();            \
};

// WRONG:
#define someMacro(X)        \
/* This comment is also     \
 * a problem. */            \
class X : public otherClass \
{                           \
     int foo;               \
     void doFoo();          \
};

// OK:
#define someMacro(X)                \
/* This comment is fine. */         \
class X : public otherClass         \
{                                   \
     int foo; /* This is OK too! */ \
     void doFoo();                  \
};

0 votes

Qu'est-ce qui ne va pas avec le numéro 2 ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X