Espacios de nombres
Variantes
Acciones

Fase de la traducción

De cppreference.com
< cpp‎ | language

El compilador procesa el archivo fuente C++ como si tuvieran lugar las siguientes fases, en este orden exacto:

Contenido

[editar] Fase 1

1) Los bytes individuales del archivo de código fuente son convertidos (de la manera que define la implementación) a caracteres del conjunto de caracteres básicos de fuente. En particular, los finales de línea dependientes del sistema operativo se reemplazan por caracteres de nueva línea. El conjunto de caracteres básico de fuente consiste en 96 caracteres:
a) 5 caracteres de espacio en blanco (espacio, tabulación horizontal, tabulación vertical, retorno de carro, nueva línea)
b) 10 caracteres de dígitos desde '0' hasta '9'
c) 52 letras desde 'a' hasta 'z' y desde 'A' hasta 'Z'
d) 29 símbolos de puntuación:_ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Cualquier carácter del archivo fuente que no se puede convertir en un carácter del conjunto de caracteres básico de fuente se reemplazan por su nombre universal de carácter (escapado con \u o \U) o por alguna forma definida por la implementación que se maneja de forma equivalente.
3) Las secuencias de trigrafos se reemplazan por su representación de carácter único correpondiente.
(hasta C++17)

[editar] Fase 2

1) cuando aparece una barra invertida al final de una línea (seguida inmediatamente del carácter de nueva línea), se elimina la barra invertida y el carácter de nueva línea, combinando las dos líneas físicas en una línea lógica. Es una operación de un paso: una línea terminada con dos barras invertidas seguidas de una línea vacía no combina tres líneas en una. Si se forma un nombre de carácter universal (\uXXXX) en esta fase, el comportamiento es indeterminado.
2) Si una línea del fuente no vacía no termina con un carácter de nueva línea después de este paso (si originalmente no tenía el carácter de nueva línea, o termina con una barra invertida), el comportamiento es indeterminado (hasta C++11)se añade un carácter de nueva línea al final (desde C++11).

[editar] Fase 3

1) Se descompone el archivo fuente en comentarios, secuencias de caracteres de espacios en blanco (espacio, tabulador horizontal, nueva línea, tabulador vertical, y retorno de carro), y elementos de preprocesamiento, que son los siguientes:
a) nombres de cabecera como <iostream> o "myfile.h"
c) números de preprocesamiento
d) Literales carácter y cadena , incluyendo definidos por usuario (desde C++11)
e) operadores y símbolos de puntuación (incluyendo elementos alternativos), como +, <<=, new, <%, ##, o and
f) caracteres individuales, no espacio en blanco, que no entran en otra categoría
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)
3) Cada comentario se sustituye con un carácter de espacio.

Se mantienen las nuevas líneas, y no especifica si las las secuencias de espacios en blanco que no son de nueva línea pueden colapsarse en caracteres de un solo espacio.

Si la entrada se analizó a elementos de preprocesamiento hasta un carácter dado, generalmente el siguiente elemento de preprocesamiento se toma como la secuencia más larga de caracteres que podría constituir un elemento de preprocesamiento, incluso si eso hace que falle el análisis que le sigue. Esto se conoce comunmente como maximal munch.

int foo = 1;
int bar = 0xE+foo;   // error, número de preproceso no válido 0xE+foo
int baz = 0xE + foo; // OK
 
int quux = bar+++++baz; // error: bar++ ++ +baz, no bar++ + ++baz.

Las únicas excepciones a la regla maximal munch son:

  • Si el siguiente carácter inicia una secuencia de caracteres que podría ser el prefijo y las comillas dobles iniciales de una literal cadena sin formato, el próximo elemento de preprocesamiento será un literal de cadena sin formato. El literal consiste en la secuencia de caracteres más corta que cumple el patrón de cadena sin formato.
#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
  • Si los siguientes tres caracteres son <:: y el carácter subsiguiente no es : ni >, se trata < como un elemento de preprocesamiento por si mismo (y no como el primer carácter del elemento alternativo <:).
struct Foo { static const int v = 1; };
std::vector<::Foo> x; // OK, <: no se entiende como el elemento alternativo para [
extern int y<::>;     // OK, lo mismo que extern int y[].
int z<:::Foo::value:>; // OK, int z[::Foo::value];
(desde C++11)
  • Los elementos de preprocesamiento de nombre de cabecera solo se forman dentro de una directiva #include
std::vector<int> x; // OK, <int> no es el nombre de una cabecera


[editar] Fase 4

1) Se ejecuta el preprocesador.
2) Cada archivo insertado con la directiva #include pasa por las fases 1 hasta 4, recursivamente.
3) al final de esta fase, se eliminan todas las directivas de preprocesador de la fuente.

[editar] Fase 5

1) Todos los caracteres en literales carácter y literales cadena se convierten del conjunto de caracteres de fuente al conjunto de caracteres de ejecución (que puede ser un conjunto de caracteres multibyte como UTF-8, siempre y cuando los 96 caracteres del conjunto 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 carácter y literales cadena se expanden y se convierten al conjunto de caracteres de ejecución. Si el carácter especificado mediante un nombre universal de carácter no es miembro del conjunto 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 -finput-charset para especificar la codificación del conjunto de caracteres del fuente, -fexec-charset y -fwide-exec-charset para especificar la codificación del conjunto de caracteres de ejecución en literales de carácter y cadena que no tienen un prefijo de codificación (desde C++11), mientras Visual Studio 2015 Update 2 y posteriores usa /source-charset y /execution-charset para especificar los conjuntos de caracteres de fuente y de ejecución respectivamente.

[editar] Fase 6

Los literales cadena contiguos se concatenan.

[editar] Fase 7

Tiene lugar la compilación: cada elemento de preprocesamiento se convierte en un token. Los tokenes son analizados sintácticamente y semánticamente y traducidos como una unidad de traducción.

[editar] Fase 8

Se examina cada unidad de traducción para producir una lista de instancias de plantillas requeridas, incluidos los solicitados por instancias explícitas. Se localiza la definiciones de las plantillas, se realizan las instanciaciones requeridas para producir unidades de instanciación.

[editar] 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.

[editar] Notas

Algunos compiladores no implementan las unidades de instanciación (también conocidas como repositorio de plantillas o registros de plantillass) 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 esplícitamente, y luego el enlazador une esas instancias compiladas en una en la fase 9.

[editar] Referencias

  • C++11 standard (ISO/IEC 14882:2011):
  • 2.2 Phases of translation [lex.phases]
  • C++98 standard (ISO/IEC 14882:1998):
  • 2.1 Phases of translation [lex.phases]

[editar] Ver también

Documentacion C de fases de traducción