it-swarm.it

Avviso del compilatore "No newline alla fine del file"

Qual è il motivo del seguente avviso in alcuni compilatori C++?

Nessuna nuova riga alla fine del file

Perché dovrei avere una riga vuota alla fine di un file sorgente/intestazione?

180
LeChuck2k

Pensa ad alcuni dei problemi che possono verificarsi se non c'è una nuova riga. Secondo lo standard ANSI il #include di un file all'inizio inserisce il file esattamente com'è all'inizio del file e non inserisce la nuova riga dopo il #include <foo.h> dopo il contenuto del file. Quindi, se includi un file senza una nuova riga alla fine del parser, verrà visualizzato come se l'ultima riga di foo.h si trova sulla stessa riga della prima riga di foo.cpp. E se l'ultima riga di foo.h fosse un commento senza una nuova riga? Ora la prima riga di foo.cpp è commentato. Questi sono solo un paio di esempi dei tipi di problemi che possono insinuarsi.


Volevo solo indicare alle parti interessate la risposta di James qui sotto. Mentre la risposta sopra è ancora corretta per C, il nuovo standard C++ (C++ 11) è stato modificato in modo che questo avviso non debba più essere emesso se si utilizza C++ e un compilatore conforme a C++ 11.

Dallo standard C++ 11 tramite il post di James:

Un file di origine che non è vuoto e che non termina con un carattere di nuova riga o che termina con un carattere di nuova riga immediatamente preceduto da un carattere di barra rovesciata prima che avvenga una siffatta giunzione, deve essere elaborato come se un nuovo il carattere di linea è stato aggiunto al file (C++ 11 §2.2/1).

210
TJ Seabrooks

Il requisito che ogni file di origine terminasse con una nuova riga senza escape è stato rimosso in C++ 11. La specifica ora recita:

Un file di origine che non è vuoto e che non termina con un carattere di nuova riga o che termina con un carattere di nuova riga immediatamente preceduto da un carattere di barra rovesciata prima che avvenga una siffatta giunzione, deve essere elaborato come se un nuovo il carattere di linea è stato aggiunto al file (C++ 11 §2.2/1).

Un compilatore conforme non dovrebbe più emettere questo avviso (almeno non durante la compilazione in modalità C++ 11, se il compilatore ha modalità per diverse revisioni delle specifiche del linguaggio).

42
James McNellis

La norma C++ 03 [2.1.1.2] dichiara:

... Se un file di origine che non è vuoto non termina con un carattere di nuova riga o termina con un carattere di nuova riga immediatamente preceduto da un carattere barra rovesciata prima che si verifichi tale giunzione, il comportamento non è definito.

24
Igor Semenov

La risposta per "obbediente" è "perché lo standard C++ 03 afferma che il comportamento di un programma che non termina con la nuova riga non è definito" (parafrasato).

La risposta per i curiosi è qui: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .

15

Non si riferisce a una riga vuota, è se l'ultima riga (che può contenere contenuto) è terminata con una nuova riga.

La maggior parte degli editor di testo inserisce una nuova riga alla fine dell'ultima riga di un file, quindi se l'ultima riga non ne ha una, esiste il rischio che il file sia stato troncato. Tuttavia, ci sono validi motivi per cui potresti non voler la nuova riga, quindi è solo un avvertimento, non un errore.

6
Leigh Caldwell

#include sostituirà la sua riga con il contenuto letterale del file. Se il file non termina con una nuova riga, la riga che contiene #include che lo ha inserito si unirà alla riga successiva.

5
moonshadow

Ovviamente in pratica ogni compilatore aggiunge una nuova riga dopo #include. Per fortuna. - @mxcl

non specifico C/C++ ma un dialetto C: quando si utilizza GL_ARB_shading_language_include extension il compilatore glsl su OS X ti avverte NON su una newline mancante. Quindi puoi scrivere un MyHeader.h file con una protezione dell'intestazione che termina con #endif // __MY_HEADER_H__ e tu sarà perdi la linea dopo il #include "MyHeader.h" di sicuro.

2
Jan-Philip Loos

Perché il comportamento differisce tra le versioni C/C++ se il file non termina con la nuova riga. Soprattutto brutto è il vecchio C++ - versioni, fx in C++ 03 lo standard dice (fasi di traduzione):

Se un file di origine che non è vuoto non termina con un carattere di nuova riga o termina con un carattere di nuova riga immediatamente preceduto da un carattere barra rovesciata, il comportamento non è definito.

Il comportamento indefinito è negativo: un compilatore conforme standard potrebbe fare più o meno ciò che vuole qui (inserire un codice dannoso o altro) - chiaramente un motivo di avvertimento.

Mentre la situazione è migliore in C++ 11, è una buona idea evitare situazioni in cui il comportamento non è definito nelle versioni precedenti. La specifica C++ 03 è peggiore di C99 che proibisce completamente tali file (il comportamento viene quindi definito).

2
skyking

Sto usando c-free IDE versione 5.0, nel mio programma del linguaggio 'c ++' o 'c' stavo riscontrando lo stesso problema. Solo alla fine del programma ovvero ultima riga del programma (dopo le parentesi graffe della funzione può essere principale o qualsiasi funzione), premere invio - il numero di riga verrà aumentato di 1. quindi eseguire lo stesso programma, verrà eseguito senza errori.

2
divesh

Questo avviso potrebbe anche aiutare a indicare che un file potrebbe essere stato troncato in qualche modo. È vero che il compilatore probabilmente genererà comunque un errore del compilatore - specialmente se si trova nel mezzo di una funzione - o forse un errore del linker, ma questi potrebbero essere più enigmatici e non è garantito che si verifichino.

Ovviamente anche questo avviso non è garantito se il file viene troncato immediatamente dopo una nuova riga, ma potrebbe comunque rilevare alcuni casi in cui potrebbero mancare altri errori e dare un suggerimento più forte al problema.

0
mwfearnley