2012-08-05 13 views
6
#define B 100+B 
main() 
{ 
    int i= B; 
} 

Yo sé que está mal, pero sólo por curiosidad, cuando compilo que recibí este extraño error:¿Cómo funciona una macro de preprocesador?

"B was not declared in this scope".

¿Por qué es así? Si este error se debió a que el compilador elimina la macro después de su sustitución, ¿cómo funciona el siguiente código bien, cuando B debe haber sido eliminado antes de que estuviera disponible para A?

#define B 100 
#define A 100+B 
main() 
{ 
    int i= B; 
    int j =A; 
} 
+4

Eso es inválida C++, por cierto . –

+3

Colocar espacios en un solo lado del operador '=' es tan feo ... –

+2

@RadekSlupik Pero al menos están en lados diferentes en las dos líneas, lo que hace que parezca algo divertido. –

Respuesta

14

Aquí está la salida del preprocesador:

gcc -E x.c 
# 1 "x.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "x.c" 

main() 
{ 
    int i= 100+B; 
} 

Como se puede ver, lo hizo el substituion. Ahora viene el paso de compilación que falla porque no se ha declarado B.

El otro código está bien, aquí está la salida:

main() 
{ 
    int i= 100; 
    int j =100+100; 
} 
+5

* Preprocesador *, no * precompilador * – Praetorian

+0

Thx, corregido .. –

+0

¿Cómo generó esta salida del preprocesador? código? – cirronimbo

9

expansión macro no se realiza de forma recursiva, si el nombre de la macro aparece en el texto de reemplazo, no se expande de nuevo. Así que con

#define B 100 + B 

un reemplazo de B se obtiene la secuencia de tokens 100 + B y B no se expande de nuevo (si lo fuera, tendría un bucle). Entonces el compilador ve una referencia a la variable no declarada B después de que el preprocesador finalizó.

Pero en

#define B 100 
#define A 100 + B 

cuando se expande la macro A, el nombre de la macro B aparece en el texto de reemplazo. Luego se amplía B y el compilador ve 100 + 100 que no contiene referencias a variables no declaradas.

+2

Esta respuesta debería tener un tic. Sólo digo'. –

0

sustitución de macros son operaciones simples de texto. Puede depurar este tipo de problema en una simple compilación paso a paso.

uso cc -E filename.c -O filename.i

para generar código extendido c

vi filename.i para la lectura de código puro/C ampliada

Cuestiones relacionadas