va_args macro define visual-c++ gcc c-preprocessor stringification

visual-c++ - macro - define c++



Diferencias en macro## operador de concatenación entre Visual-C++ y gcc (3)

De acuerdo con el estándar C, el resultado del operador de preprocesamiento '' ## '' debe ser un ''token de preprocesamiento'' o el resultado no está definido (C99 6.10.3.3 (3) - El operador ##).

La lista de tokens de preprocesamiento es (C99 6.4 (3) - Elementos léxicos):

nombres de encabezado, identificadores, números de preprocesamiento, constantes de caracteres, literales de cadenas, puntuadores y caracteres únicos de espacios no blancos que no combinan léxicamente con las otras categorías de tokens de preprocesamiento.

GCC le informa que está ingresando en un territorio indefinido. MSVC está silenciosamente satisfecho con el resultado indefinido (eso es lo que esperarías que sucediera).

Tenga en cuenta que si no está creando un solo token de todos modos, entonces no necesita el operador de pegado del token. Generalmente (estoy seguro de que probablemente haya una o dos excepciones), 2 tokens separados por espacios en blanco son equivalentes a 2 tokens no separados por espacios en blanco, como en su ejemplo.

Tengo una macro como esta (no exactamente, pero la función es bastante equivalente):

#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value ... STRUCTMEMBER(Item,1);

Esto funciona perfectamente en Visual C ++, pero gcc 3.4.5 (MingGW) produce el siguiente error:

pegando "." y "Artículo" no da un token de preprocesamiento válido

Esto también ocurre cuando uso el operador "->". No encontré pistas sobre la concatenación, que el uso de estos operadores está prohibido.

Alguien tiene alguna idea ?


De los documentos del preprocesador de gcc c :

Sin embargo, dos tokens que no forman juntos un token válido no se pueden pegar juntos.

structure.member no es un solo token.

En este caso, no necesita usar el operador ## (concatenación de token). Puedes simplemente eliminarlo. Aquí hay un ejemplo probado con gcc 4.2.4 en Linux:

#include <stdio.h> #define STRUCTMEMBER(Member, Value) GlobalStructInstance.Member = Value struct { const char* member1; }GlobalStructInstance; int main(void) { STRUCTMEMBER(member1, "Hello!"); printf("GlobalStructInstance.member1 = %s/n", GlobalStructInstance.member1); return 0; }


Tal vez Visual C ++ está pegando un par de espacios para crear otro espacio. No es que los espacios en blanco sean tokens, sino que permitirían que tu código funcione.

object.member no es un token, son tres tokens, por lo que no necesitas token-topping para implementar la macro que describes. Simplemente elimina el ''##'' y debería funcionar en todas partes.

[Editar: recién marcado, y el resultado de usar ## para formar algo que no es un token válido no está definido. Entonces GCC puede rechazarlo y MSVC puede ignorarlo y no pegar, por lo que yo sé.]