Pregunta

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:

  

pegar ". " y " Artículo " no proporciona un token de preprocesamiento válido

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

¿Alguien tiene una idea?

¿Fue útil?

Solución

Quizás Visual C ++ esté pegando un par de espacios juntos para hacer otro espacio. No es que los espacios en blanco sean tokens, pero permitiría que su código funcione.

object.member no es un token, son tres tokens, por lo que no necesita pegar token para implementar la macro que describe. Simplemente elimine el '##' y debería funcionar en todas partes.

[Editar: acabo de marcar, y el resultado de usar ## para formar algo que no es un token válido no está definido. Así que GCC puede rechazarlo y MSVC puede ignorarlo y no realizar ninguna pegada, por lo que puedo decir.]

Otros consejos

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 cadena, signos de puntuación y caracteres únicos que no corresponden a espacios en blanco que no coinciden de forma léxica con las otras categorías de token de preprocesamiento.

GCC le permite saber que está ingresando a un territorio no definido. MSVC está en silencio feliz con el resultado indefinido (eso es lo que cabría esperar que sucediera).

Tenga en cuenta que si no está creando un solo token de todos modos, entonces no necesita el operador de pegado de token. En general (estoy seguro de que probablemente haya una excepción o dos), 2 tokens separadas por espacios en blanco equivalen a 2 tokens no separadas por espacios en blanco, como en su ejemplo.

De la gcc c preprocesador de documentos :

  

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

structure.member no es un único token.

En este caso, no necesita utilizar el operador ## (concatenación de token). Usted puede 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;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top