Was ist der Grund für die folgende Warnung in einigen C++ - Compilern?
Keine neue Zeile am Ende der Datei
Warum sollte ich am Ende einer Quell-/Header-Datei eine leere Zeile haben?
Denken Sie an einige Probleme, die auftreten können, wenn kein Zeilenumbruch vorliegt. Gemäß dem ANSI-Standard fügt das #include
Einer Datei am Anfang die Datei genau so ein, wie sie sich vor der Datei befindet, und fügt die neue Zeile nach dem #include <foo.h>
Nach dem Inhalt von nicht ein die Datei. Wenn Sie also eine Datei ohne neue Zeile am Ende des Parsers einfügen, wird angezeigt, als ob sich die letzte Zeile von foo.h
In derselben Zeile wie die erste Zeile von foo.cpp
Befindet. Was wäre, wenn die letzte Zeile von foo.h ein Kommentar ohne neue Zeile wäre? Jetzt ist die erste Zeile von foo.cpp
Auskommentiert. Dies sind nur einige Beispiele für Probleme, die auftreten können.
Ich wollte nur alle Interessenten auf James 'Antwort hinweisen. Während die obige Antwort für C immer noch korrekt ist, wurde der neue C++ - Standard (C++ 11) so geändert, dass diese Warnung nicht mehr ausgegeben werden sollte, wenn C++ und ein C++ 11-konformer Compiler verwendet werden.
Vom C++ 11-Standard über James 'Post:
Eine Quelldatei, die nicht leer ist und nicht mit einem Zeichen in einer neuen Zeile oder einem Zeichen in einer neuen Zeile endet, dem unmittelbar vor dem Spleißen ein Backslash-Zeichen vorangestellt ist, wird so verarbeitet, als ob eine zusätzliche neue Zeile hinzugefügt würde. Zeilenzeichen wurden an die Datei angehängt (C++ 11 §2.2/1).
Die Anforderung, dass jede Quelldatei mit einem nicht maskierten Zeilenumbruch endet, wurde in C++ 11 entfernt. Die Spezifikation lautet nun:
Eine Quelldatei, die nicht leer ist und nicht mit einem Zeichen in einer neuen Zeile endet, oder die mit einem Zeichen in einer neuen Zeile endet, dem unmittelbar vor dem Spleißen ein Backslash-Zeichen vorangestellt ist, wird so verarbeitet, als ob eine zusätzliche neue Zeile hinzugefügt würde. Zeilenzeichen wurden an die Datei angehängt (C++ 11 §2.2/1).
Ein konformer Compiler sollte diese Warnung nicht mehr ausgeben (zumindest nicht beim Kompilieren im C++ 11-Modus, wenn der Compiler Modi für verschiedene Revisionen der Sprachspezifikation hat).
C++ 03 Standard [2.1.1.2] erklärt:
... Wenn eine Quelldatei, die nicht leer ist, nicht in einem Zeichen mit einer neuen Zeile endet oder in einem Zeichen mit einer neuen Zeile, vor dem unmittelbar ein Backslash-Zeichen steht, bevor ein solches Spleißen stattfindet, ist das Verhalten undefiniert.
Die Antwort für "gehorsam" lautet "weil der C++ 03-Standard das Verhalten eines Programms, das nicht in Zeilenumbrüchen endet, nicht definiert" (umschrieben).
Die Antwort für die Neugierigen ist hier: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .
Es bezieht sich nicht auf eine leere Zeile, sondern darauf, ob die letzte Zeile (die Inhalt enthalten kann) mit einer neuen Zeile abgeschlossen wird.
Die meisten Texteditoren setzen eine neue Zeile an das Ende der letzten Zeile einer Datei. Wenn die letzte Zeile also keine enthält, besteht die Gefahr, dass die Datei abgeschnitten wurde. Es gibt jedoch triftige Gründe, warum Sie die neue Zeile möglicherweise nicht verwenden möchten, sodass es sich nur um eine Warnung und nicht um einen Fehler handelt.
#include
ersetzt die Zeile durch den wörtlichen Inhalt der Datei. Wenn die Datei nicht mit einer neuen Zeile endet, wird die Zeile mit dem #include
, das es eingezogen hat, wird mit der nächsten Zeile zusammengeführt.
In der Praxis fügt natürlich jeder Compiler nach dem # include eine neue Zeile hinzu. Gott sei Dank. - @mxcl
nicht spezifisches C/C++, sondern ein C-Dialekt: Bei Verwendung der Erweiterung GL_ARB_shading_language_include
warnt der glsl-Compiler unter OS X Sie NICHT über einen fehlenden Zeilenumbruch . Sie können also eine MyHeader.h
- Datei mit einem Header-Guard schreiben, der mit #endif // __MY_HEADER_H__
Endet, und Sie werden verlieren mit Sicherheit die Zeile nach dem #include "MyHeader.h"
.
Weil das Verhalten zwischen C/C++ - Versionen unterschiedlich ist, wenn die Datei nicht mit new-line endet. Besonders unangenehm sind ältere C++ - Versionen, fx in C++ 03 heißt es im Standard (Übersetzungsphasen):
Wenn eine Quelldatei, die nicht leer ist, nicht in einem Zeichen mit einer neuen Zeile oder in einem Zeichen mit einer neuen Zeile endet, dem ein umgekehrter Schrägstrich unmittelbar vorausgeht, ist das Verhalten undefiniert.
Undefiniertes Verhalten ist schlecht: Ein standardkonformer Compiler könnte hier mehr oder weniger das tun, was er will (schädlichen Code einfügen oder was auch immer) - eindeutig ein Grund zur Warnung.
Während die Situation in C++ 11 besser ist, ist es eine gute Idee, Situationen zu vermeiden, in denen das Verhalten in früheren Versionen undefiniert ist. Die C++ 03-Spezifikation ist schlechter als C99, was solche Dateien völlig verbietet (Verhalten wird dann definiert).
Ich benutze c-free IDE Version 5.0, in meinem Programm entweder 'c ++' oder 'c' Sprache bekam ich das gleiche Problem.Nur am Ende des Programms dh letzte Zeile des Programms (nach geschweiften Klammern kann es sich um eine Haupt- oder eine beliebige Funktion handeln), drücken Sie die Eingabetaste - Die Zeilennummer wird um 1 erhöht. Wenn dasselbe Programm ausgeführt wird, wird es ausgeführt ohne Fehler.
Diese Warnung kann auch dazu beitragen, anzuzeigen, dass eine Datei möglicherweise abgeschnitten wurde. Es ist wahr, dass der Compiler wahrscheinlich ohnehin einen Compiler-Fehler auslöst - insbesondere, wenn er sich mitten in einer Funktion befindet - oder einen Linker-Fehler, der jedoch möglicherweise kryptischer ist und dessen Auftreten nicht garantiert ist.
Natürlich kann diese Warnung auch dann nicht garantiert werden, wenn die Datei unmittelbar nach einem Zeilenumbruch abgeschnitten wird. Es kann jedoch dennoch vorkommen, dass andere Fehler fehlen und das Problem deutlicher hervorgehoben wird.