Ich habe ein kleines Problem mit einem Präprozessor, das mich verwirrt und ich kann keine Erklärung dafür in der Dokumentation / Präprozessor / Sprachspezifikation finden.
%Vor%ist vorverarbeitet in:
%Vor%Nach der Behandlung von Trigraphs, fortgesetzten Zeilen und Kommentaren arbeitet der Präprozessor an Präprozessor-Direktiven und teilt Eingaben in Vorverarbeitungstoken und Leerzeichen. booboo's Ersetzungsliste besteht aus einem pp-Token mit der Kennung 'aaa'. booboo () bbb ist in pp-Token unterteilt: 'booboo', '(', ')', 'bbb'. Die Sequenz von 'booboo', '(', ')' wird als funktionaler Makroaufruf erkannt und sollte auf 'aaa' erweitert werden, und imho sollte in Ausgabe wie 'aaabbb' aussehen. Ich sagte, es sieht so aus, als würde es für einen Menschen wie ein Token aussehen, während der Compiler 2 Token 'aaa' und 'bbb' bekommen würde, da kein '##' Operator verwendet wurde, der pp-token Verkettung erlaubt. Warum / welche Regel macht cpp (c preprocessor) zusätzlichen Platz zwischen 'aaa' und 'bbb', wenn 'booboo (). Bbb' 'aaa.bbb' ohne Leerzeichen ergibt?
Liegt das daran, dass cpp versucht, die Ausgabe (die für den Menschen meistens ist) unangreifbar zu machen? Der Mensch ist nicht in der Lage zu sagen, dass 'aaabbb' aus 2 Token besteht, da nur die Schreibweise von Token angezeigt wird. Habe ich recht? Ich habe C99 Dokumentation über Präprozessor und Gcc-Dokumentation für cpp gelesen. Ich sehe nichts davon.
Wenn ich Recht habe, haben wir hier eine ähnliche Situation:
%Vor%ergibt:
%Vor%Sonst (wenn '++' die Ausgabe ist) würde es für einen Menschen wie '++' Token aussehen, aber es würde 2 Token '+' und '+' geben. Ist es wie mit dem Operator '##', dass cpp prüft, ob die Verkettung ein gültiges Token erzeugt, aber in den gezeigten Fällen verhindern will, dass die Verkettung durchgeführt wurde? '+ -' ist nicht mehrdeutig, also kein Leerzeichen hinzugefügt
Das Ergebnis der Vorverarbeitung besteht darin, die Quelldatei in eine Liste von Token umzuwandeln. In Ihrem Fall würde die Liste der Tokens nach der Tokenisierung aussehen:
%Vor%und dann nach dem Makroersatz:
%Vor%Dann übersetzt der Compiler die Liste der Token in eine ausführbare Datei.
Der weiße Bereich, den Sie sehen, ist nur ein Implementierungsdetail, das Ihr Compiler usw. gewählt hat, um die Vorverarbeitungstoken auszulegen, wenn Ihnen ein Zwischenergebnis angezeigt wird. Die Standards sagen nichts über Dateien zur Zwischenverarbeitung aus. Es ist nicht erforderlich, dass es ein separates Programm für die Vorverarbeitung gibt.
Ich habe in den frühen 90ern selbst einen ANSI C Compiler geschrieben. Soweit ich mich erinnere, sollte ein Kommentartoken /....../ durch einen einzelnen Leerraum ersetzt werden. Makros ersetzen den Text an Ort und Stelle. Es ist nicht notwendig, dass die Token, die sich aus dem Textersatz solcher Makroexpansion (en) ergeben, legale C-Sprachtokens sind. Wenn ein Makro als Text 'aaa' definiert ist, kommt nur der Text 'aaa' in den Eingabestrom. Der Parser von C sieht möglicherweise keine gültigen Token!
Daher gegeben:
Das Erweitern von booboo () bbb sollte den Text aaabbb ergeben
Was der aaabbb bedeutet, ist Sache des Benutzers. Aber das aaabbb wird nicht vorverarbeitet, auch wenn es der Name eines Makros ist. Das ist sicher. Aber aaabbb könnte eine Benutzerkennung sein - keine Probleme dort.
Tags und Links c c++ c-preprocessor