2016-09-05 2 views
4

Pourquoi deux littéraux de chaîne séparés par un espace, une tabulation ou un «\ n» peuvent-ils être compilés sans erreur?Compilation des littéraux de chaîne

int main() 
{ 
    char * a = "aaaa" "bbbb"; 
} 

"AAAA" est un char * "bbbb" est un char *

Il n'y a pas de règle spécifique de concaténation pour traiter deux chaînes littérales. Et, évidemment, le code suivant donne une erreur lors de la compilation:

#include <iostream> 
int main() 
{ 
    char * a = "aaaa"; 
    char * b = "bbbb"; 
    std::cout << a b; 
} 

Est-ce concaténation commun à tous les compilateurs? Où est la fin nulle de "aaaa"? Est-ce que "aaaabbbb" est un bloc continu de RAM?

+5

Ce sont des tableaux char, pas des pointeurs –

Répondre

9

Si vous voyez par ex. this translation phase reference en phase 6, il le fait:

Les littéraux de chaîne adjacents sont concaténés.

Et c'est exactement ce qui se passe ici. Vous avez deux littéraux de chaîne adjacents, et ils sont concaténés en un seul littéral de chaîne.

C'est un comportement standard.

Cela fonctionne uniquement pour les littéraux de chaîne, pas pour les variables à deux pointeurs, comme vous l'avez remarqué.

2

Les littéraux de chaîne placés côte à côte sont concaténés en phase de traduction 6 (après le préprocesseur). Autrement dit, "Hello," " world!" donne la (simple) chaîne "Hello, world!". Si les deux chaînes ont le même préfixe d'encodage (ou aucune n'a de préfixe), la chaîne résultante aura le même préfixe d'encodage (ou pas de préfixe).

(source)

5

Dans cette déclaration

char * a = "aaaa" "bbbb"; 

le compilateur dans une étape de compilation avant l'analyse syntaxique considère littéraux de chaîne adjacents comme un littéral.

Donc, pour le compilateur l'énoncé ci-dessus est équivalente à

char * a = "aaaabbbb"; 

qui est le compilateur enregistre une seule chaîne littérale "aaaabbbb"

4

littéraux de chaîne adjacents sont concaténées selon les règles de C (et C++) la norme. Mais aucune règle de ce type n'existe pour les identifiants adjacents (c'est-à-dire les variables a et b).

Pour citer, C de 14 (draft N3797), § 2.14.5:

Dans la phase de traduction 6 (2,2), les chaînes littérales sont adjacentes concaténés. Si les deux littéraux de chaîne ont le même préfixe de codage, , le littéral de chaîne concaténé résultant a ce préfixe de codage. Si un littéral de chaîne n'a pas de préfixe de codage, il est traité comme une chaîne littéral du même préfixe de codage que l'autre opérande.Si un jeton littéral de chaîne UTF-8 est adjacent à un jeton littéral à chaîne large, le programme est mal formé. Toute autre concaténation est prise en charge conditionnelle avec un comportement défini par l'implémentation.

3

En C et C++ compile les littéraux de chaîne adjacents comme un seul littéral de chaîne. Par exemple ceci:

"Some text..." "and more text" 

est équivalent à:

"Some text...and more text" 

que pour des raisons historiques:

La langue d'origine C a été conçu en 1969-1972 lors du calcul était encore dominé par le 80 colonnes perforées. Ses concepteurs ont utilisé 80 dispositifs de colonne tels que le Teletype ASR-33. Ces périphériques n'emballaient pas automatiquement le texte, ce qui incitait vraiment à conserver le code source dans les 80 colonnes. Fortran et Cobol avaient des mécanismes de continuation explicites pour le faire, avant de finalement passer au format libre. C'était un coup de génie pour Dennis Ritchie (je suppose) de réaliser qu'il n'y avait pas d'ambiguïté dans la grammaire et que de longues chaînes ASCII pouvaient être faites pour entrer dans 80 colonnes par le simple expédient de faire concaténer le compilateur chaînes littérales adjacentes. D'innombrables programmeurs C étaient reconnaissants pour cette petite fonctionnalité.

Une fois que la fonction est activée, pourquoi est-elle supprimée? Cela ne cause aucun chagrin et est souvent utile. Pour ma part, d'autres langues l'ont fait. La tendance moderne est d'avoir des chaînes étendues avec des guillemets ou d'autres symboles, mais la simplicité de cette fonctionnalité en C n'a jamais été en reste.

Similar question here.

+1

D'où avez-vous obtenu cette citation? – anatolyg

+0

@anatolyg Ajout de références –