Dieses Dokument in Abschnitt 2.6 Computed Includes enthält den folgenden Absatz:
Wenn die Zeile zu einem Token-Stream erweitert wird, der mit einem <Token beginnt und ein> Token enthält, werden die Token zwischen dem <und dem ersten> kombiniert, um den einzuschließenden Dateinamen zu bilden. Jedes Leerzeichen zwischen Token wird auf ein einzelnes Leerzeichen reduziert. dann wird jedes Leerzeichen nach dem Anfangsbuchstaben <beibehalten, ein nachfolgendes Leerzeichen vor dem Schließen> wird jedoch ignoriert . CPP sucht nach der Datei gemäß den Regeln für Winkelklammern.
Ich weiß, dass dies eine definierte Implementierung ist, aber warum muss dies für GCC so sein? Ich beziehe mich speziell auf den hervorgehobenen Satz oben.
BEARBEITEN
Ich habe gerade bemerkt, dass der dritte Absatz vor dem oben zitierten Folgendes besagt:
Sie müssen vorsichtig sein, wenn Sie das Makro definieren.
#define
speichert Token, keinen Text. Der Präprozessor kann nicht wissen, dass das Makro als Argument für verwendet wird#include
, und generiert daher normale Token, keinen Headernamen. Es ist unwahrscheinlich, dass dies zu Problemen führt, wenn Sie doppelte Anführungszeichen verwenden, die nahe genug an Zeichenfolgenkonstanten liegen. Wenn Sie jedoch spitze Klammern verwenden, können Probleme auftreten .
Weiß jemand, auf welche Probleme hier hingewiesen wird?
quelle
Antworten:
Ich denke, der Implementierer hat den einfachsten Weg gewählt, als er diese Funktionalität implementiert hat, ohne viel darüber nachzudenken.
Es scheint, dass die erste Implementierung am 03.07.2000 (vor zwei Jahrzehnten!) Gelandet ist. Der relevante Teil sieht aus wie ( Quelle ):
Insbesondere bricht es aus, wenn es das
CPP_GREATER
Token (dh>
) sieht , bevor Speicher für das Token reserviert wird. Dies ist sinnvoll, da kein Speicher zugewiesen werden muss, wenn das Token nicht in den Puffer geschrieben wird.Erst nachdem der Speicher reserviert wurde, prüft der Präprozessor, ob dem Token ein Leerzeichen (
t->flags & PREV_WHITE
) vorangestellt ist, und schreibt dann ein Leerzeichen in den Puffer.Infolgedessen werden in
< foo / bar >
nur die Leerzeichen vorfoo
( dh nach dem Anfangsbuchstaben<
)/
undbar
beibehalten.quelle
if (t->flags & PREV_WHITE) CPP_PUTC_Q (pfile, ' ');
widerspricht, was in dem Dokument gesagt wird: "Jedes Leerzeichen zwischen Token wird auf ein einzelnes Leerzeichen reduziert; ..."?