Jaki jest powód następującego ostrzeżenia w niektórych kompilatorach C ++?
Brak nowego wiersza na końcu pliku
Dlaczego powinienem mieć pustą linię na końcu pliku źródłowego / nagłówka?
c++
compiler-construction
warnings
c-preprocessor
Brian Tompsett - 汤 莱恩
źródło
źródło
cat
plik i nie ma on końca nowej linii, ponieważ monit o nową powłokę pojawi się po ostatnim wierszu pliku (tj. Nie w kolumnie 0)Why should I have an empty line at the end of a source/header file
- Jeśli plik tekstowy zawiera,one\ntwo\nthree\n
wówczas zawiera trzy wiersze, z których żaden nie jest pusty. Jeśli plik tekstowy zawieraone\ntwo\nthree
, to nie jest to plik tekstowy, w tym samym sensie, że zdanie bez kropki na końcu nie jest zdaniem.Odpowiedzi:
Pomyśl o niektórych problemach, które mogą wystąpić, jeśli nie ma nowej linii. Zgodnie ze standardem ANSI
#include
plik na początku wstawia plik dokładnie tak, jak jest na początku pliku i nie wstawia nowego wiersza po#include <foo.h>
zawartości pliku. Jeśli więc do analizatora składni zostanie dołączony plik bez nowej linii na końcu, zostanie on wyświetlony tak, jakby ostatni wiersz znajdował sięfoo.h
w tym samym wierszu, co pierwszy wierszfoo.cpp
. Co jeśli ostatni wiersz foo.h był komentarzem bez nowego wiersza? Teraz pierwszy wierszfoo.cpp
jest skomentowany. To tylko kilka przykładów rodzajów problemów, które mogą się wkraść.Chciałem tylko wskazać zainteresowanym stronom odpowiedź Jamesa poniżej. Chociaż powyższa odpowiedź jest nadal poprawna dla C, nowy standard C ++ (C ++ 11) został zmieniony, tak że to ostrzeżenie nie powinno być dłużej wyświetlane, jeśli używasz C ++ i kompilatora zgodnego z C ++ 11.
Ze standardu C ++ 11 za pośrednictwem posta Jamesa:
źródło
Wymóg, aby każdy plik źródłowy kończył się nieoznakowanym znakiem nowej linii został usunięty w C ++ 11. Specyfikacja brzmi teraz:
Kompilator zgodny nie powinien już wydawać tego ostrzeżenia (przynajmniej nie podczas kompilacji w trybie C ++ 11, jeśli kompilator ma tryby dla różnych wersji specyfikacji języka).
źródło
C ++ 03 Standard [2.1.1.2] deklaruje:
źródło
Odpowiedź na „posłuszny” brzmi „ponieważ standard C ++ 03 mówi, że zachowanie programu nie kończącego się na nowej linii jest niezdefiniowane” (parafraza).
Odpowiedź dla ciekawskich znajduje się tutaj: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .
źródło
Nie odnosi się do pustej linii, chodzi o to, czy ostatni wiersz (który może zawierać treść) kończy się nową linią.
Większość edytorów tekstu umieszcza nowy wiersz na końcu ostatniego wiersza pliku, więc jeśli ostatni wiersz go nie ma, istnieje ryzyko, że plik został obcięty. Istnieją jednak ważne powody, dla których możesz nie chcieć nowego wiersza, więc jest to tylko ostrzeżenie, a nie błąd.
źródło
#include
zastąpi jego linię dosłowną zawartością pliku. Jeśli plik nie kończy się na nowej linii, linia zawierająca tę,#include
która go wciągnęła, połączy się z kolejną linią.źródło
Korzystam z c-free IDE w wersji 5.0, w moim programie albo w języku „c ++” albo „c” otrzymywałem ten sam problem, tylko na końcu programu, tj. W ostatnim wierszu programu (po nawiasach funkcji może to być główna lub dowolna funkcja), naciśnij enter -line no. zostanie zwiększona o 1. następnie uruchom ten sam program, będzie działał bezbłędnie.
źródło
nie konkretny C / C ++, ale dialekt C: podczas korzystania z
GL_ARB_shading_language_include
rozszerzenia kompilator glsl w OS X ostrzega NIE o brakującym nowym wierszu . Więc można napisaćMyHeader.h
plik z osłoną nagłówka, który kończy się#endif // __MY_HEADER_H__
i będzie tracić linię po#include "MyHeader.h"
na pewno.źródło
Ponieważ zachowanie różni się między wersjami C / C ++, jeśli plik nie kończy się na nowej linii. Szczególnie nieprzyjemne są starsze wersje C ++, fx w C ++ 03 standard mówi (fazy tłumaczenia):
Niezdefiniowane zachowanie jest złe: kompilator zgodny ze standardem mógłby zrobić mniej więcej to, czego chce tutaj (wstawić złośliwy kod lub cokolwiek innego) - wyraźnie powód ostrzeżenia.
Chociaż sytuacja jest lepsza w C ++ 11, dobrym pomysłem jest unikanie sytuacji, w których zachowanie jest niezdefiniowane we wcześniejszych wersjach. Specyfikacja C ++ 03 jest gorsza niż C99, która wprost zabrania takich plików (następnie definiowane jest zachowanie).
źródło
#include
dyrektywą , a niektórzy programiści atakujący takie kompilatory mogli wykorzystać takie zachowanie. Pozostawienie Standardowego pozostawienia takich niezdefiniowanych elementów pozwoliłoby dobrze zdefiniować programy wykorzystujące takie dziwactwa na platformach, które określają takie zachowanie. Posiadanie standardowego mandatu spowodowałoby uszkodzenie takich programów.To ostrzeżenie może również pomóc wskazać, że plik mógł zostać w jakiś sposób obcięty. Prawdą jest, że kompilator prawdopodobnie i tak wyrzuci błąd kompilatora - szczególnie jeśli znajduje się w środku funkcji - lub może błąd linkera, ale mogą one być bardziej tajemnicze i nie ma gwarancji, że wystąpią.
Oczywiście to ostrzeżenie nie jest również gwarantowane, jeśli plik zostanie obcięty natychmiast po nowej linii, ale nadal może wychwycić niektóre przypadki, w których inne błędy mogą zostać pominięte, i daje silniejszą wskazówkę na temat problemu.
źródło
To nie jest błąd. To tylko ostrzeżenie.
Otwórz plik w edytorze, przejdź do ostatniego wiersza pliku i naciśnij klawisz Enter, aby dodać pusty wiersz na końcu pliku.
Chociaż poza tym powinieneś używać
#include <iostream>
zamiast<iostream.h>
. Następnie włóżusing std::cout;
po nim.źródło