2016-05-13 8 views
7

Offensichtlich verursacht der Compiler über das @ Zeichen einen Syntaxfehler (außer es ist ein Kommentar oder ein String-Literal). Wenn das Zeichen jedoch z.B. innerhalb eines #if 0 Blocks, ist das Programm technisch gültig?Ist das @ -Zeichen in der C-Quelle erlaubt?

Ich versuchte dies:

#define NOTHING(x) 

int main() 
{ 
    NOTHING(@@@@); 
    return 0; 
} 

mit -pedantic -Wall -Wextra, sowohl auf gcc und Klirren und es gab keine Warnungen. Ich bin mir nicht sicher, ob das garantiert funktionieren wird, oder ob sie keine spezielle Warnung dafür haben.

Ich habe nichts im Standard gefunden, der die eine oder andere Art sagt, die besorgniserregend ist. Ich möchte ein Tool nicht darauf aufbauen, nur um herauszufinden, dass ein standardkompatibler Compiler daran erstickt.

Antwort

9

Sie können fast jedes Zeichen in ein C-Programm aufnehmen, sofern es vom Präprozessor entweder gelöscht oder mit String-Zeichen versehen wurde. @ ist ein gültiges Präprozessor-Token, daher wird es in den Vorverarbeitungsphasen der Kompilierung nicht als Fehler gekennzeichnet.

Der Standard verhindert nicht, dass ein Compiler Warnungen über irgendetwas ausgibt, und es ist möglich, dass ein Compiler in diesem Fall eine Warnung erzeugt. Aber ich weiß nicht, was das tut, und ich würde es als ein Problem der Qualität der Implementierung betrachten.

einschlägigen Standard Sektionen:

  • Definition von Vorverarbeitung-token in § 6.4: "jede nicht-Leerraumzeichen, die nicht einer der obigen sein kann". Beachten Sie, dass @@@@ daher vier Vorverarbeitungstoken ist.

  • § 6,4/2, Hervorhebung hinzugefügt: „Jede Token Vorverarbeitung, die mit einem Token umgewandelt wird die lexikalische Form eines Schlüsselwort hat, eine Kennung, eine Konstante, eine Stringliteral oder einen Interpunktionssetzer“. Solange die @ nicht in ein Token "konvertiert" werden, ist kein Fehler aufgetreten. Die Umwandlung in ein Token erfolgt in Phase 7 des Übersetzungsvorgangs (siehe § 5.1.1.2/7). Das ist lange nach der Expansion von Makros, die stringification umfasst, in Phase 4.

+4

„@ ist ein gültiger Präprozessor-Token“ - das ist der Schlüssel hier, und der entsprechende Standard-Teil scheint zu sein, [C11 Abschnitt 6.4] (http://port70.net/~nsz/c/c11/n1570.html#6.4), wobei die Definition von 'Preprocessing-Token' jedes Nicht-Whitespace-Zeichen enthält, das nicht mit den anderen Vorverarbeitungstokenkategorien übereinstimmt. – user2357112

+0

Danke! Das beantwortet meine Frage vollständig. – mtijanic

Verwandte Themen