Über # # - Präprozessor in C
Gegeben
#define cat(x,y) x##y
Den Anruf cat(a,1)
zurück a1
, aber cat(cat(1,2),3)
ist nicht definiert.
Allerdings, wenn ich auch definieren #define xcat(x,y) cat(x,y)
, dann ist das Ergebnis von xcat(xcat(1,2),3)
ist jetzt 123
. Kann jemand bitte im detail erklären, warum das so ist?
- Meinst du
then the result of xcat(xcat(1,2),3) is now 123
? - Ich habe einen Fehler gemacht beim schreiben der Frage .Ja das Ergebnis von xcat(xcat(1,2),3) 123
Du musst angemeldet sein, um einen Kommentar abzugeben.
Getestet habe ich dies sowohl mit Hilfe von GCC und Clang.
GCC gibt den Fehler:
Clang gibt den Fehler:
Was anscheinend passiert ist, dass der compiler umschließt das Ergebnis
cat(1,2)
in Klammern, sobald Sie erweitert ist; also, wenn Sie rufencat(1,2)
im code, es gibt Ihnen wirklich(12)
. Dann ruftcat((12),3)
führt wiederum zu((12)3)
, die kein gültiges token, und dies führt zu einem Kompilierungsfehler.Die Allgemeine Meinung ist, "wenn mit dem token einfügen operator ( # # ) verwenden, sollten Sie zwei Ebenen der Dereferenzierung" (D. H., verwenden Sie Ihre
xcat
workaround). Sehen Warum brauche ich eine doppelte Schicht der Dereferenzierung für Makros? und Was sollte getan werden, mit Makros, müssen fügen Sie zwei Token zusammen?.In xcat(x,y), x und y sind nicht benachbart zu der # # - operator, und
damit Sie erfahren makro-expansion, bevor Sie ersetzt wird.
Also x ist identifiziert als xcat(1,2) und y identifiziert wird als 3. Aber vor
die substitution ist x makro-erweitert um die Katze(1,2), die verwandelt sich in 1##2
die sich zum 12. Also letztlich xcat(xcat(1,2),3) erweitern
cat(12,3), die wiederum aus 123.
Dies Funktioniert --> Katze(xcat(1,2),3) --> cat(cat(1,2),3) --> Katze(12,3)
Verhalten ist gut definiert, weil alle token oklejki
Ergebnis in gültigen Präprozessor-tokens ich.e jede erweitert xPression Varianten sollte ein Gültiger token in jedem Stadium.
xcat(cat(1,2),3)
hab ja sowieso schon.Ich glaube nicht, dass, wenn die Katze tatsächlich werde ausgebaut, die 2-mal in Folge. Das ist, warum ich Frage mich, warum würde der compiler auch produzieren, wie eine Nachricht wie
'pasting ")" and "3" does not give a valid preprocessing token'
.Auch denke ich nicht, dass die innere Katze wird erstmals erweitert. Also, ich nehme an, der Ausgang wäre
cat(1,2)3
. Dass mich direkt zum nachdenken an, wie würde der compiler zu interpretieren.