Domanda

Sto avendo una macro come questa (non esattamente, ma la funzione è abbastanza equivalente):

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

Funziona perfettamente in Visual C ++, ma gcc 3.4.5 (MingGW) produce il seguente errore:

  

incollare ". " e "Articolo" non fornisce un token di preelaborazione valido

Questo succede anche quando uso il pulsante " - > " operatore. Non ho trovato suggerimenti sulla concatenazione, secondo cui l'uso di questi operatori è vietato.

Qualcuno ha un'idea?

È stato utile?

Soluzione

Forse Visual C ++ sta incollando un paio di spazi insieme per creare un altro spazio. Non che gli spazi bianchi siano token, ma consentirebbe al tuo codice di funzionare.

object.member non è un token, è tre token, quindi non è necessario incollare token per implementare la macro che descrivi. Rimuovi "##" e dovrebbe funzionare ovunque.

[Modifica: appena spuntato, e il risultato dell'uso di ## per formare qualcosa che non è un token valido non è definito. Quindi GCC può rifiutarlo e MSVC può ignorarlo e non eseguire incolla, per quanto ne so.]

Altri suggerimenti

Secondo lo standard C, il risultato dell'operatore di preelaborazione " ## " deve essere un "token di preelaborazione" o il risultato non è definito (C99 6.10.3.3 (3) - Il ## operatore).

L'elenco dei token di preelaborazione è (C99 6.4 (3) - Elementi lessicali):

  

nomi di intestazione, identi, numeri di preelaborazione, costanti di carattere, valori letterali di stringa, segni di punteggiatura e singoli caratteri non bianchi che non corrispondono lessicamente alle altre categorie di token di preelaborazione.

GCC ti fa sapere che stai entrando in un territorio non definito. MSVC è silenziosamente contento del risultato indefinito (è quello che ti aspetteresti che accada).

Nota che se non stai creando comunque un singolo token, non hai bisogno dell'operatore di incollare token. Generalmente (sono sicuro che ci sono probabilmente un'eccezione o due), 2 token separati da spazi bianchi equivalgono a 2 token non separati da spazi bianchi - come nel tuo esempio.

Dai gcc c preprocessor docs :

  

Tuttavia, due token che non formano insieme un token valido non possono essere incollati insieme.

structure.member non è un singolo token.

In questo caso non è necessario utilizzare l'operatore ## (concatenazione di token). Puoi semplicemente rimuoverlo. Ecco un esempio testato con gcc 4.2.4 su 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top