Namespaces
Variants

Phases of translation

From cppreference.net

Le fichier source C est traité par le compilateur comme si les phases suivantes se déroulaient, dans cet ordre précis. L'implémentation réelle peut combiner ces actions ou les traiter différemment tant que le comportement reste identique.

Table des matières

Phase 1

1) Les octets individuels du fichier source (qui est généralement un fichier texte dans un encodage multioctet tel que UTF-8) sont mappés, de manière définie par l'implémentation, aux caractères du jeu de caractères source . En particulier, les indicateurs de fin de ligne dépendants du système d'exploitation sont remplacés par des caractères de nouvelle ligne.
Le jeu de caractères source est un jeu de caractères multioctet qui inclut le jeu de caractères source de base comme sous-ensemble mono-octet, constitué des 96 caractères suivants :
a) 5 caractères d'espacement (espace, tabulation horizontale, tabulation verticale, saut de page, saut de ligne)
b) 10 caractères numériques de '0' à '9'
c) 52 lettres de 'a' à 'z' et de 'A' à 'Z'
d) 29 caractères de ponctuation : _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Les séquences de trigraphes sont remplacées par les représentations à caractère unique correspondantes. (jusqu'en C23)

Phase 2

1) Chaque fois qu'un antislash apparaît à la fin d'une ligne (immédiatement suivi du caractère de nouvelle ligne), l'antislash et la nouvelle ligne sont supprimés, combinant deux lignes physiques de source en une seule ligne logique de source. Il s'agit d'une opération à passage unique : une ligne se terminant par deux antislashs suivie d'une ligne vide ne combine pas trois lignes en une.
#include <stdio.h>
#define PUTS p\
u\
t\
s
/* Line splicing is in phase 2 while macros
 * are tokenized in phase 3 and expanded in phase 4,
 * so the above is equivalent to #define PUTS puts
 */
int main(void)
{
 /* Use line splicing to call puts */ PUT\
S\
("Output ends here\\
0Not printed" /* After line splicing, the remaining backslash
               * escapes the 0, ending the string early.
               */
);
}
2) Si un fichier source non vide ne se termine pas par un caractère de nouvelle ligne après cette étape (qu'il n'ait pas eu de nouvelle ligne à l'origine, ou qu'il se soit terminé par un antislash), le comportement est indéfini.

Phase 3

1) Le fichier source est décomposé en commentaires , séquences de caractères d'espacement (espace, tabulation horizontale, saut de ligne, tabulation verticale et saut de page), et preprocessing tokens , qui sont les suivants
a) noms d'en-tête : < stdio. h > ou "myfile.h"
c) les nombres de prétraitement, qui incluent les constantes entières et les constantes flottantes , mais couvrent également certains jetons invalides tels que 1 .. E + 3. foo ou 0JBK
e) opérateurs et ponctuateurs, tels que + , <<= , < % , ou ## .
f) caractères individuels non-blancs qui ne correspondent à aucune autre catégorie
2) Chaque commentaire est remplacé par un caractère d'espace
3) Les sauts de ligne sont conservés, et il est défini par l'implémentation si les séquences d'espaces blancs autres que les sauts de ligne peuvent être réduites à des caractères d'espace uniques.

Si l'entrée a été analysée en tokens de prétraitement jusqu'à un caractère donné, le prochain token de prétraitement est généralement considéré comme la plus longue séquence de caractères qui pourrait constituer un token de prétraitement, même si cela devait entraîner l'échec de l'analyse ultérieure. Ceci est communément appelé maximal munch .

int foo = 1;
// int bar = 0xE+foo; // erreur : nombre de prétraitement invalide 0xE+foo
int bar = 0xE/*Comment expands to a space*/+foo; // OK : 0xE + foo
int baz = 0xE + foo; // OK : 0xE + foo
int pub = bar+++baz; // OK : bar++ + baz
int ham = bar++-++baz; // OK : bar++ - ++baz
// int qux = bar+++++baz; // erreur : bar++ ++ +baz, pas bar++ + ++baz
int qux = bar+++/*Saving comment*/++baz; // OK : bar++ + ++baz

La seule exception à la règle de la prise maximale est :

#define MACRO_1 1
#define MACRO_2 2
#define MACRO_3 3
#define MACRO_EXPR (MACRO_1 <MACRO_2> MACRO_3) // OK : <MACRO_2> n'est pas un nom d'en-tête

Phase 4

1) Preprocessor est exécuté.
2) Chaque fichier introduit par la directive #include passe par les phases 1 à 4, de manière récursive.
3) À la fin de cette phase, toutes les directives du préprocesseur sont supprimées de la source.

Phase 5

1) Tous les caractères et séquences d'échappement dans les constantes de caractère et les littéraux de chaîne sont convertis du jeu de caractères source vers le jeu de caractères d'exécution (qui peut être un jeu de caractères multioctet tel que UTF-8, tant que les 96 caractères du jeu de caractères source de base listés dans la phase 1 ont des représentations sur un seul octet). Si le caractère spécifié par une séquence d'échappement n'est pas membre du jeu de caractères d'exécution, le résultat est défini par l'implémentation, mais il est garanti de ne pas être un caractère (large) nul.

Note : la conversion effectuée à cette étape peut être contrôlée par des options de ligne de commande dans certaines implémentations : gcc et clang utilisent - finput - charset pour spécifier l'encodage du jeu de caractères source, - fexec - charset et - fwide - exec - charset pour spécifier les encodages du jeu de caractères d'exécution dans les littéraux de chaîne et les constantes caractères qui n'ont pas de préfixe d'encodage (depuis C11) .

Phase 6

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

Phase 7

La compilation a lieu : les jetons sont analysés syntaxiquement et sémantiquement et traduits en tant qu'unité de traduction.

Phase 8

La liaison a lieu : les unités de traduction et les composants de bibliothèque nécessaires pour satisfaire les références externes sont collectés dans une image de programme qui contient les informations nécessaires à l'exécution dans son environnement d'exécution (le système d'exploitation).

Références

  • Norme C23 (ISO/IEC 9899:2024) :
  • 5.1.1.2 Phases de traduction (p: TBD)
  • 5.2.1 Jeux de caractères (p: TBD)
  • 6.4 Éléments lexicaux (p: TBD)
  • Norme C17 (ISO/CEI 9899:2018) :
  • 5.1.1.2 Phases de traduction (p: 9-10)
  • 5.2.1 Jeux de caractères (p: 17)
  • 6.4 Éléments lexicaux (p: 41-54)
  • Norme C11 (ISO/IEC 9899:2011) :
  • 5.1.1.2 Phases de traduction (p: 10-11)
  • 5.2.1 Jeux de caractères (p: 22-24)
  • 6.4 Éléments lexicaux (p: 57-75)
  • Norme C99 (ISO/CEI 9899:1999) :
  • 5.1.1.2 Phases de traduction (p : 9-10)
  • 5.2.1 Jeux de caractères (p : 17-19)
  • 6.4 Éléments lexicaux (p : 49-66)
  • Norme C89/C90 (ISO/CEI 9899:1990) :
  • 2.1.1.2 Phases de traduction
  • 2.2.1 Jeux de caractères
  • 3.1 Éléments lexicaux

Voir aussi

Documentation C++ pour Phases de traduction