afaik, cette question s'applique également à Étape 6 des "phases de traduction" spécifiées dans la norme eliben@eliben-desktop:~/test$ cat cpptest.c
int a = 5;
"string 1" "string 2"
"string 3"
eliben@eliben-desktop:~/test$ cpp cpptest.c
# 1 "cpptest.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "cpptest.c"
int a = 5;
"string 1" "string 2"
"string 3"
5 Réponses :
Sauf si le prétraiteur n'est spécifié pour gérer cela, il est prudent de supposer que c'est le travail du compilateur. P>
EDIT: P>
Votre " IE " Le lien au début de la poste répond à la question: p>
Les littéraux à chaîne adjacents sont concatérés au moment de la compilation; Cela permet à de longues chaînes d'être scindées sur plusieurs lignes et permet également aux littéraux de chaîne résultant de C pré-processeur défini et macros em> à être ajouté aux chaînes au moment de la compilation em> ... p> blockQuote>
Cependant, dans tous les cas, cela se passe avant de convertir les jetons de préprocesseur en jetons réels. Par exemple, les rendements suivants 5 code> au lieu d'une analyse d'analyse:
taille de "12" "34" code>
@Johannes: Qu'en est-il de Tailleof "12" "23" code> a quelque chose à voir avec les jetons de préprocesseur?
@David: Le mot-clé sizeof i> ne prend qu'un seul argument. Donnez-lui deux variables et cela se plaindre.
@Karmastan: les chaînes sont concaténées dans la phase 6 de la traduction et Taillef code> est évaluée dans la phase 7. La phase 4 est lorsque les jetons de préprocesseur sont traités.
Taille de code> n'est pas un jeton de préprocesseur au moment de son évaluation.
@David Ce que je dis, c'est que les littéraux de chaîne sont concaténés avant que les jetons de préprocesseur soient convertis en flux de jetons réels. Parce que la syntaxe abstraite est taille de littéral code> et non
taille de littéral littéral code>. C'est un jeton non-pp lorsque le jeton-ruisseau a été converti et est analysé par phase 7 en C ++ et C. Je ne dis pas que
taille de code> est évalué à temps de prétraitement.
@Johannes: Mes excuses, je me suis confus par le "préprocesseur" dans "jeton de préprocesseur". Oui, la concaténation est la phase 6 et la conversion des jetons de prétraitement est au début de la phase 7.
La norme ne spécifie pas un compilateur préprocesseur contre un compilateur, il spécifie simplement les phases de la traduction que vous avez déjà notées. Traditionnellement, les phases 1 à 4 étaient dans le préprocesseur, les phases 5 bien que 7 dans le compilateur et la phase 8 de la liaison - mais rien de tout cela n'est requis par la norme. P>
Cela signifie-t-il que le CPP de GCC ne se conforme pas à cette tradition de manipulation de 1 à 6 au RPC?
@Eli: voir la réponse éditée / correcte. Je pense que ça colle assez près de la tradition (réelle).
dans la norme ANSI C, ce détail est couvert à la section 5.1.1.2, élément (6): p>
5.1.1.2 Phases de traduction
...
de
4. Les directives de prétraitement sont exécutées et les invocations macro sont élargies. ...
de
5. Chaque élément de jeu de caractères source et séquence d'échappée dans les constantes de caractères et les littéraux de chaîne sont convertis en un élément du jeu de caractères d'exécution.
de
6. Les jetons littéraux de la chaîne de caractères adjacents sont concaténés et des jetons littéraux à chaîne large adjacents sont concaténés. P> blockQuote>La norme ne définit pas que la mise en œuvre doit utiliser un pré-processeur et un compilateur, en soi. p>
L'étape 4 est clairement une responsabilité de préprocesseur. P>
Étape 5 nécessite que le "jeu de caractères d'exécution" soit connu. Ces informations sont également requises par le compilateur. Il est plus facile de porter le compilateur à une nouvelle plate-forme si le prétraiteur ne contient pas de dépendances de la plate-forme, de sorte que la tendance est d'implémenter l'étape 5 et donc l'étape 6, dans le compilateur. P>
Je le gérerais dans la partie de jeton de balayage de l'analyseur, donc dans le compilateur. Il semble plus logique. Le préprocesseur n'a pas à connaître la "structure" de la langue et, en fait, il l'ignore généralement pour que les macros puissent générer un code inaboutable. Il ne gère rien de plus que ce qu'il est habilité à gérer par des directives qui lui sont spécifiquement adressées ( # ... code>) et les "conséquences" d'entre eux (comme celles d'un
#define xH code>, qui rendrait le pré-processeur changer beaucoup de x dans h) p>
c'est-à-dire une ouverture ", des trucs, une fermeture", suivis de "blancs", puis suivis d'ouverture "la fermeture" (et ainsi de suite), ne provoquera pas de produire deux jetons à chaîne à être ensuite fusionné: il produirait un seul jeton à cordes directement
Il existe des règles difficiles pour la concaténation littérale à chaîne interagit avec des séquences d'échappement.
Supposons que vous ayez alors x1 code> et
x2 code> doit s'éloigner égal selon
STRCMP code>, et le même Pour
Y1 code> et
Y2 code>. (C'est ce qu'est la santé en citant les étapes de traduction - la conversion d'évasion se produit avant em> la concaténation constante de la chaîne.) Il existe également une exigence que si tout em> des constantes de chaîne dans un Le groupe de concaténation a un
l code> ou
u code> préfixe, vous obtenez une chaîne large ou unicode. Mettez-le tous ensemble et il s'agit d'être significativement plus pratique de faire ce travail dans le cadre du "compilateur" plutôt que du "préprocesseur". p> p>
Je pense que cela ne pourrait pas être géré par le pré-processeur, car vous pouvez utiliser des macros pour émettre des littéraux à chaîne, ce qui peut être adjacent aux autres. Comme le préprocesseur n'est pas multi-laissez-passer, il n'a pas la possibilité de résoudre ce cas.
@Évan: cela ne pourrait-il pas être traité par la carte de concaténation à la chaîne qui se produit après la passation de macro expansion? Si vous y réfléchissez, si la cordon concacte est la "chose" i> last i> autre
cpp code> fait, il est indiscernable de son être dans le compilateur :-)