2016-07-21 7 views
1

Ich versuche, X-Makros und Preprozessor-Verkettung, beide zum ersten Mal, zusammen zu verwenden.Verketten Sie mehrere Token für X-Makro

Ich habe eine Menge der anderen Fragen über SO im Zusammenhang mit Preprozessor-Verkettung gelesen, aber noch nicht in der Lage, meinen Kopf um sie herum zu wickeln oder wie diese an meinen Anwendungsfall anzupassen.

Die Liste der Elemente ist eine Liste von ID-Nummern für eine Reihe von structs, etwa so:

#define LIST_OF_ID_NUMS \ 
    X(1) \ 
    X(2) \ 
    X(3) \ 
    X(4) \ 
    X(5) \ 
    X(6) \ 
    X(7) \ 
    X(8) \ 
    X(9) \ 
    X(10) \ 
    X(11) 

ich die structs wie so erklären kann:

#define X(id_num) static myFooStruct foo_## id_num ; 
LIST_OF_ID_NUMS 
#undef X 
// gives: 'struct myFooStruct foo_n;' where 'n' is an ID number 

Jetzt möchte ich auch um eines der Mitglieder jeder Struktur zu initialisieren, um gleich der ID-Nummer zu sein, so dass foo_n.id = n;. Ich konnte das erste Token Verkettung erreichen, indem Sie die folgende Verwendung:

#define X(id_num) foo_## id_num .id = 3 ; 
LIST_OF_ID_NUMS 
#undef X 
// gives: 'foo_n.id = x' where 'x' is some constant (3 in this case) 

Aber ich habe nicht in der Lage zu verstehen, wie richtig die Idee weiter zu erweitern, so dass der zugewiesene Wert auch ersetzt wird. Ich habe versucht:

#define X(id_num) foo_## id_num .id = ## id_num ; 
LIST_OF_ID_NUMS 
#undef X 
// Does NOT give: 'foo_n.id = n;' :(

Und verschiedene Versuche, doppelte Indirektion für die Verkettung zu verwenden. Aber waren nicht erfolgreich. Der obige Versuch führt Fehler wie die folgenden für jedes Element in der LIST_OF_ID_NUMS:

foo.c:47:40: error: pasting "=" and "1" does not give a valid preprocessing token 
    #define X(id_num) foo_## id_num .id = ## id_num ; 
            ^
foo.c:10:5: note: in expansion of macro 'X' 
    X(1) \ 
^
foo.c:48:2: note: in expansion of macro 'LIST_OF_ID_NUMS ' 
    LIST_OF_ID_NUMS 

Wie kann ich die Form am besten erreichen foo_n.id = n?

Antwort

2

Soweit ich das beurteilen kann, ist, dass sollte einfach:

#define X(id_num) foo_## id_num .id = id_num ; 
+0

Wow, das funktioniert! Darn, das bedeutet, dass ich noch weniger verstehe, als ich über die Präprozessor-Verkettung dachte: \ – Toby

+1

@Toby Du brauchst Token-Paste, um 'foo_42' (ein Token) anstelle von' foo_42' zu erhalten (zwei Token und später ein Syntaxfehler) . Aber '= 42' muss kein einzelnes Token sein (und kann auch nicht eins sein), also kein Token-Paste hier. – Quentin

+0

Ahh, Licht dämmert! Danke @Quentin – Toby

Verwandte Themen