visual-c++ c-preprocessor variadic-macros

visual c++ - MSVC no expande__VA_ARGS__ correctamente



visual-c++ c-preprocessor (3)

Considera este código:

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ #define G(...) F(__VA_ARGS__) F(1, 2, 3) G(1, 2, 3)

La salida esperada es X = 1 and VA_ARGS = 2, 3 para ambas macros, y eso es lo que X = 1 and VA_ARGS = 2, 3 con GCC, sin embargo, MSVC expande esto como:

X = 1 and VA_ARGS = 2, 3 X = 1, 2, 3 and VA_ARGS =

Es decir, __VA_ARGS__ se expande como un único argumento, en lugar de dividirse en varios.

De cualquier forma alrededor de esto?


¿Qué versión de MSVC estás usando? Necesitará Visual C ++ 2010.

__VA_ARGS__ fue presentado por primera vez por C99. MSVC nunca intentó admitir C99, por lo que no se agregó el soporte.

Ahora, sin embargo, __VA_ARGS__ está incluido en el nuevo estándar C ++, C ++ 2011 (anteriormente conocido como C ++ 0x), que Microsoft aparentemente planea admitir, por lo que ha sido admitido en versiones recientes de MSVC.

Por cierto, tendrá que usar un sufijo .cpp en su archivo fuente para obtener este soporte. MSVC no ha actualizado su interfaz C durante mucho tiempo.


El preprocesador de MSVC parece comportarse de manera bastante diferente a la especificación estándar.
Probablemente la siguiente solución ayude:

#define EXPAND( x ) x #define F(x, ...) X = x and VA_ARGS = __VA_ARGS__ #define G(...) EXPAND( F(__VA_ARGS__) )


Publiqué el siguiente problema de soporte de Microsoft :

El siguiente programa __VA_ARGS__ un error de compilación porque el precompilador expande __VA_ARGS__ incorrectamente:

#include <stdio.h> #define A2(a1, a2) ((a1)+(a2)) #define A_VA(...) A2(__VA_ARGS__) int main(int argc, char *argv[]) { printf("%d/n", A_VA(1, 2)); return 0; }

El preprocesador expande el printf a: printf ("% d / n", ((1, 2) + ()));

en lugar de printf ("% d / n", ((1) + (2)));

Recibí la siguiente respuesta insatisfactoria de un desarrollador del equipo compilador de Microsoft:

Hola: el compilador de Visual C ++ se comporta correctamente en este caso. Si combina la regla de que los tokens que coinciden con el ''...'' en la invocación de macro inicial se combinan para formar una sola entidad (16.3 / p12) con la regla de que las sub-macros se expanden antes del reemplazo del argumento (16.3.1 / p1 ) entonces, en este caso, el compilador cree que A2 se invoca con un único argumento: de ahí el mensaje de error.