Leider habe ich heute (bei der Umgestaltung eines alten gefährlichen Codes) ein wenig Codearchäologie gemacht und ein kleines Fossil gefunden:
%Vor%Ich war völlig verblüfft, einen solchen archaischen Schatz dort zu finden. Ich habe es auf einer Website für C-Programmierung nachgelesen. Es erklärte jedoch nicht, WARUM jemand es verwenden möchte. Ich war mir daher selbst überlassen zu vermuten, dass der Programmierer es rein aus reiner Freude gemacht hat, den Compiler zu belügen.
Hinweis: (Beachten Sie, dass das Fossil tatsächlich in Zeile 3 der cpp-Datei war) (Oh, und die Datei zeigte tatsächlich auf eine .y-Datei, die fast identisch mit dieser Datei war.
Weiß jemand, warum eine solche Richtlinie benötigt wird? Oder wofür könnte es verwendet werden?
Im Allgemeinen wird es von automatisierten Code-Generierungswerkzeugen (wie yacc
oder bison
) verwendet, um die Zeilennummer auf den Wert der Zeile in der tatsächlichen Quelldatei anstatt der C
Quelldatei zu setzen.
Auf diese Weise erhalten Sie einen Fehler, der besagt:
%Vor%Sie können Zeile 15 der tatsächlichen Quelldatei betrachten, um das Problem zu sehen.
Ansonsten sagt es etwas lächerlich wie No such identifier 'xyz' on line 1723 of foo.c
und Sie müssen diese Zeile in Ihrer automatisch generierten C
-Datei manuell mit der Entsprechung in Ihrer realen Datei korrelieren. Vertrauen Sie mir, es sei denn, Sie möchten sich tief in das Innere der lexikalischen und semantischen Analyse einarbeiten (oder eine Hirnblutung), Sie möchten nicht den von yacc
generierten Code durchgehen ( bison
kann schöneren Code generieren) Ich weiß es nicht, aber es ist mir auch egal, da ich den höheren Code schreibe.)
Es hat zwei Formen gemäß dem C99-Standard:
%Vor% Der erste setzt nur die gemeldete Zeilennummer, der zweite ändert auch den gemeldeten Dateinamen, so dass Sie in Zeile 27 von foo.y
anstelle von foo.c
einen Fehler bekommen können.
"Der Programmierer hat es rein aus reiner Freude gemacht, den Compiler zu belügen", so. Wir mögen verbogen und verdreht sein, aber wir sind normalerweise nicht bösartig :-) Diese Zeile wurde von yacc
oder bison
selbst gesetzt, um dir einen Gefallen zu tun.
Der einzige Ort, an dem ich diese Funktionalität als nützlich empfunden habe, ist der generierte Code. Wenn Sie ein Werkzeug verwenden, das die C-Datei aus der in einer anderen Form definierten Quelle in einer separaten Datei (zB der ".y" -Datei) erzeugt, kann #line
dem Benutzer helfen, das "echte" Problem zu erkennen und wohin sie gehen sollen, um sie zu korrigieren (die .y-Datei, in die sie den ursprünglichen Code einfügen).
Der Zweck der Direktive #line liegt hauptsächlich in der Verwendung durch Werkzeuge - Code-Generatoren können sie verwenden, so dass Debugger (zum Beispiel) den Kontext der Dinge im Code des Benutzers behalten können, so dass Fehlermeldungen den Benutzer auf den Code verweisen können Speicherort in seiner Quelldatei.
Ich habe diese Direktive nie gesehen, die von einem Programmierer benutzt wurde, um sie manuell einzubauen - und ich bin mir nicht sicher, wie nützlich das wäre.
Es hat einen tieferen Zweck. Der ursprüngliche C-Präprozessor war ein vom Compiler getrenntes Programm. Nachdem es mehrere .h-Dateien in die .c-Datei zusammengeführt hatte, wollten die Benutzer immer noch wissen, dass die Fehlermeldung von Zeile 42 von stdio.h oder Zeile 17 von main.c kam. Ohne irgendeine Art von Kommunikation hätte der Compiler sonst keine Möglichkeit zu wissen, welche Quelldatei ursprünglich die fehlerhafte Codezeile enthielt.
Es beeinflusst auch die Tabellen, die von jedem Debugger auf Source-Level benötigt werden, um zwischen generiertem Code und Quelldatei und Zeilennummer zu übersetzen.
In diesem Fall sehen Sie sich natürlich eine Datei an, die von einem Tool geschrieben wurde (wahrscheinlich yacc oder bison), mit dem Parser aus einer Beschreibung ihrer Grammatik erstellt werden. Diese Datei ist nicht wirklich eine Quelldatei. Es wurde aus dem echten Quelltext erstellt.
Wenn Ihre Archäologie Sie zu einem Problem mit dem Parser führt, dann wollen Sie herausfinden, welcher Parsergenerator tatsächlich verwendet wird, und etwas Hintergrundleser für Parser im Allgemeinen machen, damit Sie verstehen, warum es so funktioniert alle. Die Dokumentation für Yacc, Bison oder was auch immer das Werkzeug ist, wird wahrscheinlich auch hilfreich sein.
Ich habe #line und #error verwendet, um eine temporäre * .c-Datei zu erstellen, die du kompilierst, und deine IDE gibt dir eine Liste von Fehlern, die von einem Drittanbieter-Tool gefunden wurden.
Zum Beispiel habe ich die Ausgabedatei von PC-LINT in ein Perl-Skript geleitet, das die vom Menschen lesbaren Fehler in #line- und #error-Zeilen umgewandelt hat. Dann kompilierte diese Ausgabe und meine IDE lässt mich jeden Fehler mit F4 durchlaufen. Viel schneller, als dass man jede Datei manuell öffnet und zu einer bestimmten Zeile springt.
Tags und Links c