Frage

Was ist der Grund für die folgende Warnung in einigen C ++ - Compilern?

Keine Newline am Ende der Datei

Warum sollte ich am Ende einer Quell-/Header -Datei eine leere Zeile haben?

War es hilfreich?

Lösung

Denken Sie an einige der Probleme, die auftreten können, wenn es keine Newline gibt. Nach dem ANSI -Standard die #include einer Datei am Anfang fügt die Datei genau so ein, wie sie sich an der Vorderseite der Datei befindet, und fügt die neue Zeile nach dem nicht ein #include <foo.h> Nach dem Inhalt der Datei. Wenn Sie also eine Datei ohne Newline am Ende des Parsers einfügen, wird sie so angesehen, als ob die letzte Zeile von foo.h ist in der gleichen Zeile wie die erste Zeile von foo.cpp. Was wäre, wenn die letzte Zeile von foo.h ein Kommentar ohne neue Zeile wäre? Jetzt die erste Zeile von foo.cpp wird kommentiert. Dies sind nur einige Beispiele für die Arten von Problemen, die sich kriechen können.


Ich wollte nur alle Interessenten auf James 'Antwort unten verweisen. Während die obige Antwort für C noch korrekt ist, wurde der neue C ++ - Standard (C ++ 11) geändert, sodass diese Warnung nicht mehr ausgegeben werden sollte, wenn C ++ verwendet wird, und ein Compiler, der sich an C ++ 11 entspricht.

Aus C ++ 11 Standard über James 'Post:

Eine Quelldatei, die nicht leer ist und die nicht in einem neuen Zeilencharakter endet oder der in einem neuen Zeilencharakter endet, dem ein Backslash-Charakter vor einem solchen Spleißen vorausgeht, muss so verarbeitet werden, als ob ein zusätzliches Neues Zeilenzeichen wurden an die Datei angehängt (C ++ 11 §2.2/1).

Andere Tipps

Die Anforderung, dass jede Quelldatei mit einer nicht geschmückten Newline endet, wurde in C ++ 11 entfernt. In der Spezifikation heißt es jetzt:

Eine Quelldatei, die nicht leer ist und die nicht in einem neuen Zeilencharakter endet oder der in einem neuen Zeilencharakter endet, dem ein Backslash-Charakter vor einem solchen Spleißen vorausgeht, muss so verarbeitet werden, als ob ein zusätzliches Neues Zeilenzeichen wurden an die Datei angehängt (C ++ 11 §2.2/1).

Ein konformer Compiler sollte diese Warnung nicht mehr ausstellen (zumindest nicht beim Kompilieren im C ++ 11 -Modus, wenn der Compiler Modi für verschiedene Überarbeitungen der Sprachspezifikation hat).

C ++ 03 Standard [2.1.1.2] deklariert:

... Wenn eine nicht leere Quelldatei nicht in einem neuen Zeilencharakter endet oder in einem neuen Zeilencharakter endet, vor dem ein Backslash-Zeichen vor einem solchen Spleißen vorangetrieben wird, ist das Verhalten nicht definiert.

Die Antwort auf den "gehorsamen" lautet "," weil der C ++ 03 -Standard besagt, dass das Verhalten eines Programms, das nicht in Newline endet, undefiniert ist "(paraphrasiert).

Die Antwort für die Neugierigen lautet hier: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html.

Es bezieht sich nicht auf eine leere Zeile, sondern ob die letzte Zeile (die Inhalte darin haben kann) mit einer neuen Zeile beendet wird.

Die meisten Textredakteure setzen am Ende der letzten Zeile einer Datei eine neue Zeile ein. Wenn also die letzte Zeile keine hat, besteht das Risiko, dass die Datei abgeschnitten wurde. Es gibt jedoch gültige Gründe, warum Sie die Newline möglicherweise nicht wünschen, daher ist es nur eine Warnung, kein Fehler.

#include Ersetzt seine Linie durch den buchstäblichen Inhalt der Datei. Wenn die Datei nicht mit einer neuen Zeile endet, enthält die Zeile die Zeile, die die enthält #include Das hat es mit der nächsten Zeile verschmelzen.

Ich verwende c-freie IDE-Version 5.0, in meinem Programm entweder von 'C ++' oder 'C' Sprache, das ich gleiche Problem bekam. am Ende des Programms dh die letzte Linie des Programms (nach Funktionsklammern kann es sich um Haupt- oder jede Funktion handeln).Drücken Sie Enter-Linie Nr. wird durch 1. als das gleiche Programm ausführen, es wird ohne Fehler ausgeführt.

Natürlich fügt jeder Compiler in der Praxis eine neue Zeile nach dem #include hinzu. Gott sei Dank. - @mxcl

Nicht spezifisch C/C ++, sondern ein C -Dialekt: Wenn Sie die verwenden GL_ARB_shading_language_include Erweiterung des GLSL -Compilers auf OS X warnt Sie NICHT über eine fehlende neue Linie. So können Sie eine schreiben MyHeader.h Datei mit einem Headerschutz, der mit endet mit #endif // __MY_HEADER_H__ Und Sie Wille Verliere die Linie nach der #include "MyHeader.h" mit Sicherheit.

Da sich das Verhalten zwischen C/C ++-Versionen unterscheidet, wenn die Datei nicht mit neuer Linie endet. Besonders böse ist ältere C ++-Versionen, FX in C ++ 03 Der Standard sagt (Translationsphasen):

Wenn eine nicht leere Quelldatei nicht in einem neuen Zeilencharakter endet oder in einem neuen Zeilenzeichen endet, dem ein Backslash-Zeichen unmittelbar vorausgesetzt ist, ist das Verhalten undefiniert.

Undefiniertes Verhalten ist schlecht: Ein Standard -Konformations -Compiler könnte mehr oder weniger das tun, was es hier will (fügen Sie böswilligen Code oder was auch immer ein) - eindeutig ein Grund für die 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, das solche Dateien vollständig verbietet (das Verhalten wird dann definiert).

Diese Warnung könnte auch helfen, anzuzeigen, dass eine Datei irgendwie abgeschnitten werden könnte. Es ist wahr, dass der Compiler wahrscheinlich ohnehin einen Compiler -Fehler werfen wird - insbesondere wenn er sich in der Mitte einer Funktion befindet - oder vielleicht einen Linker -Fehler, aber diese könnten kryptischer sein und nicht garantiert auftreten.

Natürlich ist diese Warnung auch nicht garantiert, wenn die Datei unmittelbar nach einer neuen Linie abgeschnitten wird, aber sie könnte immer noch einige Fälle erfassen, in denen andere Fehler möglicherweise vermissen, und gibt einen stärkeren Hinweis auf das Problem.

Das ist kein Fehler. Es ist nur eine Warnung.

Öffnen Sie die Datei in einem Editor, gehen Sie in die letzte Zeile der Datei und drücken Sie die Eingabetaste, um zum Ende der Datei eine leere Zeile hinzuzufügen.

Außerdem sollten Sie jedoch verwenden #include <iostream> Anstatt von <iostream.h>. Dann eins using std::cout; Danach.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top