Was ist der Grund für die folgende Warnung in einigen C ++ - Compilern?
Kein Zeilenumbruch am Dateiende
Warum sollte ich am Ende einer Quell- / Header-Datei eine leere Zeile haben?
c++
compiler-construction
warnings
c-preprocessor
Brian Tompsett - 汤 莱恩
quelle
quelle
cat
eine Datei haben und sie keine nachfolgende neue Zeile enthält, da die neue Shell-Eingabeaufforderung nach der letzten Zeile der Datei erscheint (dh nicht in Spalte 0)Why should I have an empty line at the end of a source/header file
- Wenn eine Textdatei enthältone\ntwo\nthree\n
, enthält sie drei Zeilen, von denen keine leer ist. Wenn eine Textdatei enthält, handeltone\ntwo\nthree
es sich nicht um eine Textdatei, im gleichen Sinne, dass ein Satz ohne Punkt am Ende kein Satz ist.Antworten:
Denken Sie an einige der Probleme, die auftreten können, wenn keine neue Zeile vorhanden ist. Gemäß dem ANSI-Standard
#include
fügt die Datei am Anfang die Datei genau so ein, wie sie sich an der Vorderseite der Datei befindet, und fügt die neue Zeile nicht#include <foo.h>
nach dem Inhalt der Datei ein. Wenn Sie also eine Datei ohne Zeilenumbruch am Ende des Parsers einfügen, wird diese so angezeigt, als ob sich die letzte Zeile vonfoo.h
in derselben Zeile wie die erste Zeile von befindetfoo.cpp
. Was wäre, wenn die letzte Zeile von foo.h ein Kommentar ohne neue Zeile wäre? Jetzt ist die erste Zeile vonfoo.cpp
auskommentiert. Dies sind nur einige Beispiele für die Arten von Problemen, die auftreten können.Ich wollte nur Interessenten auf James 'Antwort unten hinweisen. Während die obige Antwort für C immer noch korrekt ist, wurde der neue C ++ - Standard (C ++ 11) geändert, sodass diese Warnung nicht mehr ausgegeben werden sollte, wenn C ++ und ein Compiler verwendet werden, der C ++ 11 entspricht.
Aus dem C ++ 11-Standard über James 'Post:
quelle
Die Anforderung, dass jede Quelldatei mit einem nicht maskierten Zeilenumbruch endet, wurde in C ++ 11 entfernt. Die Spezifikation lautet jetzt:
Ein konformer Compiler sollte diese Warnung nicht mehr ausgeben (zumindest nicht beim Kompilieren im C ++ 11-Modus, wenn der Compiler über Modi für verschiedene Revisionen der Sprachspezifikation verfügt).
quelle
C ++ 03 Standard [2.1.1.2] erklärt:
quelle
Die Antwort für "gehorsam" lautet "weil der C ++ 03-Standard besagt, dass das Verhalten eines Programms, das nicht mit Zeilenumbruch endet, undefiniert ist" (umschrieben).
Die Antwort für Neugierige ist hier: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .
quelle
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 am Ende der letzten Zeile einer Datei. Wenn also in der letzten Zeile keine vorhanden ist, besteht die Gefahr, dass die Datei abgeschnitten wurde. Es gibt jedoch triftige Gründe, warum Sie die neue Zeile möglicherweise nicht möchten, sodass es sich nur um eine Warnung und nicht um einen Fehler handelt.
quelle
#include
ersetzt seine Zeile durch den wörtlichen Inhalt der Datei. Wenn die Datei nicht mit einer neuen Zeile endet, wird die Zeile mit der Zeile, die sie#include
eingezogen hat, mit der nächsten Zeile zusammengeführt.quelle
Ich verwende die c-freie IDE-Version 5.0. In meinem Programm mit der Sprache 'c ++' oder 'c' trat das gleiche Problem auf. Nur am Ende des Programms, dh in der letzten Zeile des Programms (nach Klammern der Funktion) Haupt- oder eine beliebige Funktion), drücken Sie die Eingabetaste . wird um 1 erhöht. Wenn Sie dasselbe Programm ausführen, wird es ohne Fehler ausgeführt.
quelle
GL_ARB_shading_language_include
Kein spezifisches C / C ++, sondern ein C-Dialekt: Wenn Sie die Erweiterung verwenden, warnt Sie der glsl-Compiler unter OS X NICHT vor einem fehlenden Zeilenumbruch. Sie können also eineMyHeader.h
Datei mit einem Header Guard schreiben , der mit endet,#endif // __MY_HEADER_H__
und Sie werden die Zeile nach dem#include "MyHeader.h"
mit Sicherheit verlieren .quelle
Weil sich das Verhalten zwischen C / C ++ - Versionen unterscheidet, wenn die Datei nicht mit einer neuen Zeile endet. Besonders böse sind ältere C ++ - Versionen, fx in C ++ 03 sagt der Standard (Übersetzungsphasen):
Undefiniertes Verhalten ist schlecht: Ein standardkonformer Compiler kann 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 nicht definiert ist. Die C ++ 03-Spezifikation ist schlechter als C99, was solche Dateien völlig verbietet (das Verhalten wird dann definiert).
quelle
#include
Anweisung folgt Einige Programmierer, die auf solche Compiler abzielen, haben dieses Verhalten möglicherweise ausgenutzt. Wenn der Standard solche Dinge undefiniert lässt, können Programme, die solche Macken ausnutzen, auf Plattformen, die ein solches Verhalten spezifizieren, genau definiert werden. Wenn das Standardmandat ein Verhalten hätte, würde dies solche Programme brechen.Diese Warnung kann auch dazu beitragen, anzuzeigen, dass eine Datei möglicherweise abgeschnitten wurde. Es ist wahr, dass der Compiler wahrscheinlich sowieso einen Compilerfehler auslösen wird - insbesondere wenn er sich mitten in einer Funktion befindet - oder vielleicht einen Linkerfehler, aber diese könnten kryptischer sein und können nicht garantiert auftreten.
Natürlich ist diese Warnung auch nicht garantiert, wenn die Datei unmittelbar nach einem Zeilenumbruch abgeschnitten wird. In einigen Fällen kann es jedoch vorkommen, dass andere Fehler übersehen werden, und es wird ein stärkerer Hinweis auf das Problem gegeben.
quelle
Das ist kein Fehler. Es ist nur eine Warnung.
Öffnen Sie die Datei in einem Editor, gehen Sie zur letzten Zeile der Datei und drücken Sie die Eingabetaste, um am Ende der Datei eine leere Zeile einzufügen.
Abgesehen davon sollten Sie jedoch
#include <iostream>
anstelle von verwenden<iostream.h>
. Dann setzen Sie einusing std::cout;
danach.quelle