que programa ejecutar desde compilar compilador como c visual-studio gcc c-preprocessor

programa - gcc que es



Diferencia entre gcc y preprocesador de Microsoft. (3)

Creo que gcc lo hace bien, lo que Microsoft hace es incorrecto.

Cuando la macro sustitución se realiza para la línea.

M2(a, P(a, b))

el estándar (sección 6.10.3.1) requiere que antes de reemplazar el segundo parámetro ("y") en la lista de reemplazo de la macro ("M3 (x, y)") con su argumento ("P (a, b)"), macro El reemplazo debe ser realizado para ese argumento. Esto significa que "P (a, b)" se procesa a "{a, b}" antes de que se inserte, dando como resultado

M3(a, {a, b})

que luego se reemplaza a

a + {a + b}

Descubrí que el compilador de Microsoft Visual Studio y gcc preprocesan el siguiente fragmento de código de forma diferente:

# define M3(x, y, z) x + y + z # define M2(x, y) M3(x, y) # define P(x, y) {x, y} # define M(x, y) M2(x, P(x, y)) M(a, b)

''gcc -E'' da lo siguiente:

a + {a + b}

, mientras que ''cl / E'' emite una advertencia sobre un argumento de macro faltante y produce el siguiente resultado:

a + {a, b} +

Parece que las comas que provienen de macro expansiones anidadas no se consideran separadores de argumentos. Desafortunadamente, no encontré ninguna descripción del algoritmo implementado en el preprocesador cl, por lo que no estoy seguro de que mi sugerencia sea correcta. ¿Alguien sabe cómo funciona el preprocesador cl y cuál es la diferencia entre su algoritmo y el de gcc? ¿Y cómo se puede explicar el comportamiento observado?


La única lógica que explica tal comportamiento se ve así.

Forma CL:

M(a,b) M2(a,P(a,b)) M3(a,P(a,b)) M3(a,{a,b}) -> M3 gets 2 arguments ( ''a'' and ''{a,b}'') instead of 3. | / / arg1 | arg2

Manera de Gcc:

M(a,b) M2(a,P(a,b)) M3(a,P(a,b)) M3(a,{a,b}) -> Gcc probably thinks there are 3 arguments here (''a'', ''{a'', ''b}''). | | | arg1 | | arg2 | arg3


# define M3(x, y, z) x + y + z # define M2(x, y) M3(x, y) # define P(x, y) {x, y} # define M(x, y) M2(x, P(x, y)) M(a, b)

Vamos a extender esto manualmente, paso a paso:

M(a, b) --> M2(a, P(a, b)) --> M2(a, {a, b})

La norma dice:

Los argumentos individuales dentro de la lista están separados por tokens de preprocesamiento de coma, pero los tokens de preprocesamiento de coma entre paréntesis internos no se separan

solo se mencionan paréntesis, así que ...

--> M3(a, {a, b}) --> a + {a + b}

Importante:

M3(a, {a, b})

Aquí, de acuerdo con la cita anterior del estándar, se pasan tres "argumentos" a M3 (usando comillas simples para describir tokens / argumentos):

M3(''a'', ''{a'', ''b}'')

que se expanden a

''a'' + ''{a'' + ''b}''

Y esto es lo que cpp (4.6.1) da textualmente:

# 1 "cpp.cpp" # 1 "<built-in>" # 1 "<command-line>" # 1 "cpp.cpp" a + {a + b}

cpp (o gcc y g++ ) son correctos, MSVC no lo es.

Como un noble, asegúrese de que existe un informe de error.