Fases de la traducción
El compilador procesa el archivo fuente C++ como si tuvieran lugar las siguientes fases, en este orden exacto:
Fase 1
\u o \U) o por alguna otra forma definida por la implementación que se maneja de forma equivalente. (hasta C++23)|
3) Las secuencias de trígrafos se reemplazan por su representación de carácter único correspondiente.
|
(hasta C++17) |
Fase 2
\uXXXX), el comportamiento no está definido.Fase 3
<iostream> o "myfile.h";+, <<=, <%, ##, o and;|
2) Se deshacen todas las transformaciones realizadas durante las fases 1 y 2 entre las comillas dobles inicial y final de cualquier literal cadena sin formato.
|
(desde C++11) |
Se mantienen las nuevas líneas, y no se especifica si las secuencias de espacios en blanco que no son de nueva línea pueden colapsarse en caracteres de un solo espacio.
|
A medida que los caracteres del archivo fuente se examinan para conformar el siguiente token de preprocesamiento (es decir, no se analizan como parte de un comentario u otras formas de espacio en blanco), se reconocen los nombres de carácter universal y se reemplazan por el elemento designado del juego de caracteres de traducción, excepto cuando coincide con una secuencia en: b) un literal de cadena (s-char-sequence y r-char-sequence), excluyendo los delimitadores (d-char-sequence);
|
(desde C++23) |
Si la entrada se transformó en tókenes de preprocesamiento hasta un carácter dado, generalmente el siguiente token de preprocesamiento se toma como la secuencia más larga de caracteres que puede formar un token de preprocesamiento, incluso si eso causa un error en el análisis posterior. Comúnmente esto se conoce como maximal munch o "mascada máxima" debido a que el preprocesamiento "masca" un número máximo de caracteres de la entrada.
int foo = 1;
int bar = 0xE+foo; // error, preproceso erróneo de número 0xE+foo
int baz = 0xE + foo; // correcto
int quux = bar+++++baz; // error: bar++ ++ +baz, no bar++ + ++baz.
Las únicas excepciones a la regla maximal munch son:
#define R "x"
const char* s = R"y"; // literal cadena sin formato mal formada, no "x" "y"
const char* s2 = R"(a)" "b)"; // un literal de cadena sin formato seguido
// de un literal de cadena normal
struct Foo { static const int v = 1; };
std::vector<::Foo> x; // Correcto, <: no se entiende como el token alternativo para [
extern int y<::>; // Correcto, lo mismo que extern int y[].
int z<:::Foo::value:>; // Correcto, int z[::Foo::value];
|
(desde C++11) |
- Los tókenes de preprocesamiento de nombres de encabezado solo se forman dentro de una directiva
#include
std::vector<int> x; // Correcto, <int> no es el nombre de un encabezado
Fase 4
Fase 5
|
1) Todos los caracteres literales de carácter y literales cadena se convierten del juego de caracteres de fuente al juego de caracteres de ejecución (que puede ser un juego de caracteres multibyte como UTF-8, siempre y cuando los 96 caracteres del juego básico de caracteres de fuente listados en la fase 1 tengan una representación de un byte).
2) Las secuencias de escape y los nombres universales de carácter en literales de carácter y literales de cadena procesados se expanden y se convierten al juego de caracteres de ejecución.
Si el carácter especificado mediante un nombre universal de carácter no es miembro del juego de caracteres de ejecución, el resultado está definido por la implementación, pero se garantiza que no sea un carácter nulo (extenso).
Nota: la conversión realizada en esta etapa se puede controlar en algunas implementaciones mediante opciones de la línea de comandos: gcc y clang usan |
(hasta C++23) |
|
Para una secuencia de dos o más tókenes literales de cadena adyacentes, se determina un prefijo de codificación común como se específica aquí. Cada literal cadena de este tipo se considera que tiene ese prefijo común (la conversión de caracteres se mueve a la fase 3). |
(desde C++23) |
Fase 6
Los literales de cadena contiguos se concatenan.
Fase 7
Tiene lugar la compilación: cada token de preprocesamiento se convierte en un token. Los tókenes son analizados sintácticamente y semánticamente y traducidos como una unidad de traducción.
Fase 8
Se examina cada unidad de traducción para producir una lista de instancias de plantillas requeridas, incluidos las solicitadas por instancias explícitas. Se localizan las definiciones de las plantillas, se realizan las instanciaciones requeridas para producir unidades de instanciación.
Fase 9
Las unidades de traducción, las unidades de instanciación y los componentes de biblioteca necesarios para satisfacer las referencias externas se recopilan en una imagen de programa que contiene la información necesaria para la ejecución en su entorno de ejecución.
Notas
Algunos compiladores no implementan las unidades de instanciación (también conocidas como repositorio de plantillas o registros de plantillas) y simplemente compila cada instanciación de plantilla en la fase 7, almacenando el código en el archivo objeto donde se solicita implícita o explícitamente, y luego el enlazador une esas instancias compiladas en una en la fase 9.
Referencias
- El estándar C++20 (ISO/IEC 14882:2020):
- 5.2 Phases of translation [lex.phases]
- El estándar C++17 (ISO/IEC 14882:2017):
- 5.2 Phases of translation [lex.phases]
- El estándar C++14 (ISO/IEC 14882:2014):
- 2.2 Phases of translation [lex.phases]
- El estándar C++11 (ISO/IEC 14882:2011):
- 2.2 Phases of translation [lex.phases]
- El estándar C++03 (ISO/IEC 14882:2003):
- 2.1 Phases of translation [lex.phases]
- El estándar C++98 (ISO/IEC 14882:1998):
- 2.1 Phases of translation [lex.phases]
Véase también
Documentación de C para Fases de traducción
|