8
votes

Mise en œuvre de la concaténation littérale à chaîne en C et C ++

afaik, cette question s'applique également à C str forte> et c ++ em>

Étape 6 des "phases de traduction" spécifiées dans la norme c forte> (5.1.1.2 Dans le projet de norme C99) indique que les littéraux stricts adjacents doivent être concatérés en un seul littéral. IE P>

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"


2 commentaires

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 autre cpp fait, il est indiscernable de son être dans le compilateur :-)


5 Réponses :


4
votes

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.

EDIT:

Votre " IE " Le lien au début de la poste répond à la question:

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 à être ajouté aux chaînes au moment de la compilation ...


6 commentaires

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 au lieu d'une analyse d'analyse: taille de "12" "34"


@Johannes: Qu'en est-il de Tailleof "12" "23" a quelque chose à voir avec les jetons de préprocesseur?


@David: Le mot-clé sizeof 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 est évaluée dans la phase 7. La phase 4 est lorsque les jetons de préprocesseur sont traités. Taille de 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 et non taille de littéral littéral . 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 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.



9
votes

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.


2 commentaires

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).



2
votes

dans la norme ANSI C, ce détail est couvert à la section 5.1.1.2, élément (6):

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.

La norme ne définit pas que la mise en œuvre doit utiliser un pré-processeur et un compilateur, en soi.

L'étape 4 est clairement une responsabilité de préprocesseur.

É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.


0 commentaires

1
votes

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 ( # ... ) et les "conséquences" d'entre eux (comme celles d'un #define xH , qui rendrait le pré-processeur changer beaucoup de x dans h)


1 commentaires

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



1
votes

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 xxx

alors x1 et x2 doit s'éloigner égal selon STRCMP , et le même Pour Y1 et Y2 . (C'est ce qu'est la santé en citant les étapes de traduction - la conversion d'évasion se produit avant la concaténation constante de la chaîne.) Il existe également une exigence que si tout des constantes de chaîne dans un Le groupe de concaténation a un l ou u 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".


0 commentaires