Comme décrit dans ce copié-collé de description des phases de traduction de la norme C99, la suppression des commentaires (ils sont remplacés par un simple espace) intervient dans la phase de traduction 3, tandis que les directives de prétraitement sont traitées et les macros sont développées dans la phase 4.
Dans la norme C90 (que je n'ai qu'en version papier, donc pas de copier-coller) ces deux phases se déroulent dans le même ordre, bien que la description des phases de traduction soit légèrement différente dans certains détails de la norme C99 - le fait que les commentaires soient supprimés et remplacés par un seul caractère d'espacement avant que les directives de prétraitement soient traitées et les macros développées n'est pas différent.
Là encore, la norme C++ prévoit que ces deux phases se déroulent dans le même ordre.
Pour ce qui est de la façon dont le //
Les commentaires ' doivent être traités, la norme C99 le dit (6.4.9/2) :
Sauf à l'intérieur d'une constante de caractère, d'un littéral de chaîne de caractères ou d'un commentaire, les caractères // introduisent un commentaire qui inclut tous les caractères multi-octets jusqu'au, mais pas le, prochain caractère de nouvelle ligne. le prochain caractère de nouvelle ligne.
Et la norme C++ dit (2.7) :
Les caractères // commencent un commentaire, qui se termine par le prochain caractère de nouvelle ligne caractère.
Votre premier exemple est donc clairement une erreur de la part de ce traducteur - le ' ;
après le caractère foo(a)
doit être conservé lorsque le foo()
est développée - les caractères de commentaire ne doivent pas faire partie du "contenu" de la macro the foo()
macro.
Mais comme vous êtes confronté à un traducteur bogué, vous pouvez modifier la définition de la macro en :
#define foo(x) /* junk */
pour contourner le bogue.
Cependant (et je m'éloigne du sujet ici...), étant donné que la coupure de ligne (les barres obliques inversées juste avant une nouvelle ligne) se produit avant que les commentaires ne soient traités, vous pouvez rencontrer quelque chose comme ce bout de code méchant :
#define evil( x) printf( "hello "); // hi there, \
printf( "%s\n", x); // you!
int main( int argc, char** argv)
{
evil( "bastard");
return 0;
}
Ce qui pourrait surprendre celui qui l'a écrit.
Ou encore mieux, essayez ce qui suit, écrit par quelqu'un (certainement pas moi !) qui aime les commentaires en forme de boîte :
int main( int argc, char** argv)
{
//----------------/
printf( "hello "); // Hey, what the??/
printf( "%s\n", "you"); // heck?? /
//----------------/
return 0;
}
Selon que votre compilateur traitera par défaut trigraphes ou non (les compilateurs sont censés le faire, mais comme les trigraphes surprennent presque tous ceux qui les rencontrent, certains compilateurs décident de les désactiver par défaut), vous pouvez obtenir ou non le comportement que vous souhaitez - quel que soit ce comportement, bien sûr.