it-swarm-eu.dev

Compilerwarnung "Keine Zeilenumbrüche am Ende der Datei"

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?

180
LeChuck2k

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).

210
TJ Seabrooks

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).

42
James McNellis

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.

24
Igor Semenov

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 .

15

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.

6
Leigh Caldwell

#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.

5
moonshadow

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".

2
Jan-Philip Loos

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).

2
skyking

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.

2
divesh

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.

0
mwfearnley