Namespaces
Variants

Phases of translation

From cppreference.net

El archivo fuente en C es procesado por el compilador como si las siguientes fases tuvieran lugar, en este orden exacto. La implementación real puede combinar estas acciones o procesarlas de manera diferente siempre que el comportamiento sea el mismo.

Contenidos

Fase 1

1) Los bytes individuales del archivo de código fuente (que generalmente es un archivo de texto en alguna codificación multibyte como UTF-8) se mapean, de manera definida por la implementación, a los caracteres del source character set . En particular, los indicadores de fin de línea dependientes del sistema operativo se reemplazan por caracteres de nueva línea.
El source character set es un conjunto de caracteres multibyte que incluye el basic source character set como subconjunto de un solo byte, consistente en los siguientes 96 caracteres:
a) 5 caracteres de espacio en blanco (espacio, tabulación horizontal, tabulación vertical, avance de página, nueva línea)
b) 10 caracteres numéricos desde '0' hasta '9'
c) 52 letras desde 'a' hasta 'z' y desde 'A' hasta 'Z'
d) 29 caracteres de puntuación: _ { } [ ] # ( ) < > % : ; . ? * + - / ^ & | ~ ! = , \ " '
2) Las secuencias de trigrafos son reemplazadas por las representaciones de un solo carácter correspondientes. (until C23)

Fase 2

1) Siempre que aparezca una barra invertida al final de una línea (seguida inmediatamente por el carácter de nueva línea), tanto la barra invertida como la nueva línea se eliminan, combinando dos líneas físicas de código fuente en una línea lógica de código fuente. Esta es una operación de una sola pasada: una línea que termina con dos barras invertidas seguida de una línea vacía no combina tres líneas en una.
#include <stdio.h>
#define PUTS p\
u\
t\
s
/* El empalme de líneas ocurre en la fase 2 mientras las macros
 * se tokenizan en la fase 3 y se expanden en la fase 4,
 * por lo que lo anterior equivale a #define PUTS puts
 */
int main(void)
{
 /* Usar empalme de líneas para llamar a puts */ PUT\
S\
("Output ends here\\
0Not printed" /* Después del empalme de líneas, la barra invertida restante
               * escapa el 0, terminando la cadena prematuramente.
               */
);
}
2) Si un archivo fuente no vacío no termina con un carácter de nueva línea después de este paso (ya sea que no tuviera una nueva línea originalmente, o que terminara con una barra invertida), el comportamiento no está definido.

Fase 3

1) El archivo fuente se descompone en comentarios , secuencias de caracteres de espacio en blanco (espacio, tabulación horizontal, nueva línea, tabulación vertical y avance de página), y preprocessing tokens , que son los siguientes
a) nombres de cabecera: < stdio. h > o "myfile.h"
c) números de preprocesamiento, que incluyen constantes enteras y constantes flotantes , pero también incluyen algunos tokens inválidos como 1 .. E + 3. foo o 0JBK
e) operadores y puntuadores, como + , <<= , < % , o ## .
f) caracteres individuales que no son espacios en blanco y que no encajan en ninguna otra categoría
2) Cada comentario se reemplaza por un carácter de espacio
3) Los saltos de línea se conservan, y está definido por la implementación si las secuencias de espacios en blanco que no son saltos de línea pueden colapsarse en caracteres de espacio simples.

Si la entrada ha sido analizada hasta un carácter dado, el siguiente token de preprocesamiento generalmente se toma como la secuencia más larga de caracteres que podría constituir un token de preprocesamiento, incluso si eso causara que el análisis posterior falle. Esto se conoce comúnmente como maximal munch .

int foo = 1;
// int bar = 0xE+foo; // error: número de preprocesamiento no válido 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; // error: bar++ ++ +baz, no bar++ + ++baz
int qux = bar+++/*Saving comment*/++baz; // OK: bar++ + ++baz

La única excepción a la regla de máxima coincidencia es:

#define MACRO_1 1
#define MACRO_2 2
#define MACRO_3 3
#define MACRO_EXPR (MACRO_1 <MACRO_2> MACRO_3) // CORRECTO: <MACRO_2> no es un nombre de cabecera

Fase 4

1) Preprocessor se ejecuta.
2) Cada archivo introducido con la directiva #include pasa por las fases 1 a 4, de forma recursiva.
3) Al final de esta fase, todas las directivas del preprocesador son eliminadas del código fuente.

Fase 5

1) Todos los caracteres y secuencias de escape en constantes de carácter y literales de cadena se convierten del juego de caracteres de origen al juego de caracteres de ejecución (que puede ser un juego de caracteres multibyte como UTF-8, siempre que los 96 caracteres del juego de caracteres básico de origen listados en la fase 1 tengan representaciones de un solo byte). Si el carácter especificado por una secuencia de escape no es miembro del juego de caracteres de ejecución, el resultado está definido por la implementación, pero se garantiza que no será un carácter (ancho) nulo.

Nota: la conversión realizada en esta etapa puede ser controlada por opciones de línea de comandos en algunas implementaciones: gcc y clang utilizan - finput - charset para especificar la codificación del conjunto de caracteres fuente, - fexec - charset y - fwide - exec - charset para especificar las codificaciones del conjunto de caracteres de ejecución en los literales de cadena y constantes de caracteres que no tienen un prefijo de codificación (desde C11) .

Fase 6

Los literales de cadena adyacentes se concatenan.

Fase 7

La compilación tiene lugar: los tokens se analizan sintáctica y semánticamente y se traducen como una unidad de traducción.

Fase 8

El enlace tiene lugar: Las unidades de traducció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 su ejecución en su entorno de ejecución (el SO).

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 5.1.1.2 Fases de traducción (p: TBD)
  • 5.2.1 Juegos de caracteres (p: TBD)
  • 6.4 Elementos léxicos (p: TBD)
  • Estándar C17 (ISO/IEC 9899:2018):
  • 5.1.1.2 Fases de traducción (p: 9-10)
  • 5.2.1 Juegos de caracteres (p: 17)
  • 6.4 Elementos léxicos (p: 41-54)
  • Estándar C11 (ISO/IEC 9899:2011):
  • 5.1.1.2 Fases de traducción (p: 10-11)
  • 5.2.1 Conjuntos de caracteres (p: 22-24)
  • 6.4 Elementos léxicos (p: 57-75)
  • Estándar C99 (ISO/IEC 9899:1999):
  • 5.1.1.2 Fases de traducción (p: 9-10)
  • 5.2.1 Conjuntos de caracteres (p: 17-19)
  • 6.4 Elementos léxicos (p: 49-66)
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 2.1.1.2 Fases de traducción
  • 2.2.1 Conjuntos de caracteres
  • 3.1 Elementos léxicos

Véase también

Documentación de C++ para Fases de traducción