¿Cuál es el motivo de la siguiente advertencia en algunos compiladores de C++?
Sin nueva línea al final del archivo
¿Por qué debería tener una línea vacía al final de un archivo de fuente/encabezado?
Piense en algunos de los problemas que pueden ocurrir si no hay una nueva línea. De acuerdo con la norma ANSI, el #include
de un archivo al principio inserta el archivo exactamente como está en la parte frontal del archivo y no inserta la nueva línea después del #include <foo.h>
después del contenido del archivo. Por lo tanto, si incluye un archivo sin nueva línea al final del analizador, se verá como si la última línea de foo.h
estuviera en la misma línea que la primera línea de foo.cpp
. ¿Qué pasa si la última línea de foo.h fue un comentario sin una nueva línea? Ahora la primera línea de foo.cpp
está comentada. Estos son solo algunos ejemplos de los tipos de problemas que pueden surgir.
Solo quería señalar a las partes interesadas la respuesta de James a continuación. Si bien la respuesta anterior sigue siendo correcta para C, el nuevo estándar de C++ (C++ 11) se ha cambiado para que esta advertencia ya no se emita si se usa C++ y un compilador que cumpla con C++ 11.
Del estándar C++ 11 a través de la publicación de James:
Un archivo fuente que no esté vacío y que no termine en un carácter de nueva línea, o que termine en un carácter de nueva línea inmediatamente precedido por un carácter de barra diagonal invertida antes de que se produzca dicho empalme, se procesará como si se tratara de una novedad adicional. el carácter de línea se anexó al archivo (C++ 11 §2.2/1).
El requisito de que todos los archivos de origen terminen con una línea nueva sin escape se eliminó en C++ 11. La especificación ahora lee:
Un archivo fuente que no esté vacío y que no termine en un carácter de nueva línea, o que termine en un carácter de nueva línea inmediatamente precedido por un carácter de barra diagonal invertida antes de que se produzca dicho empalme, se procesará como si se tratara de una novedad adicional. el carácter de línea se anexó al archivo (C++ 11 §2.2/1).
Un compilador conforme ya no debería emitir esta advertencia (al menos no cuando compila en modo C++ 11, si el compilador tiene modos para diferentes revisiones de la especificación de lenguaje).
La norma C++ 03 [2.1.1.2] declara:
... Si un archivo de origen que no está vacío no termina en un carácter de nueva línea, o termina en un carácter de nueva línea inmediatamente precedido por un carácter de barra diagonal inversa antes de que tenga lugar tal empalme, el comportamiento es indefinido.
La respuesta para el "obediente" es "porque el estándar C++ 03 dice que el comportamiento de un programa que no termina en nueva línea no está definido" (parafraseado).
La respuesta para los curiosos está aquí: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .
No se refiere a una línea en blanco, es si la última línea (que puede tener contenido en ella) termina con una nueva línea.
La mayoría de los editores de texto colocarán una nueva línea al final de la última línea de un archivo, por lo que si la última línea no la tiene, existe el riesgo de que el archivo haya sido truncado. Sin embargo, existen razones válidas por las que no desea la nueva línea, por lo que es solo una advertencia, no un error.
#include
reemplazará su línea con el contenido literal del archivo. Si el archivo no termina con una nueva línea, la línea que contiene el #include
que lo abrió se fusionará con la siguiente línea.
Por supuesto, en la práctica, cada compilador agrega una nueva línea después de #include. Agradecidamente. - @mxcl
no es C/C++ específico, sino un dialecto C: cuando se utiliza la extensión GL_ARB_shading_language_include
, el compilador glsl en OS X le advierte a NO sobre una nueva línea que falta. Así que puede escribir un archivo MyHeader.h
con un protector de encabezado que termina con #endif // __MY_HEADER_H__
y usted perderá perderá la línea después del #include "MyHeader.h"
seguro.
Debido a que el comportamiento difiere entre las versiones de C/C++ si el archivo no termina con una nueva línea. Especialmente desagradable es la versión anterior de C++, fx en C++ 03, según el estándar (fases de traducción):
Si un archivo de origen que no está vacío no termina en un carácter de nueva línea, o termina en un carácter de nueva línea inmediatamente precedido por un carácter de barra diagonal inversa, el comportamiento no está definido.
El comportamiento indefinido es malo: un compilador estándar podría hacer más o menos lo que quiere aquí (inserte el código malicous o lo que sea), claramente una razón para advertir.
Si bien la situación es mejor en C++ 11, es una buena idea evitar situaciones en las que el comportamiento no esté definido en versiones anteriores. La especificación de C++ 03 es peor que la C99, que prohíbe totalmente tales archivos (luego se define el comportamiento).
Estoy usando c-free IDE versión 5.0, en mi programa, ya sea en el lenguaje 'c ++' o 'c', estaba teniendo el mismo problema. Justo al final del programa es decir, la última línea de el programa (después de llaves de la función puede ser principal o cualquier otra función), presione enter - line no. Se incrementará en 1. Luego ejecute el mismo programa, se ejecutará sin error.
Esta advertencia también podría ayudar a indicar que un archivo podría haber sido truncado de alguna manera. Es cierto que el compilador probablemente lanzará un error de compilación de todos modos, especialmente si está en medio de una función, o tal vez un error de vinculador, pero podría ser más críptico y no se garantiza que ocurra.
Por supuesto, esta advertencia tampoco está garantizada si el archivo se trunca inmediatamente después de una nueva línea, pero aún podría detectar algunos casos que otros errores podrían pasar por alto, y da una idea más clara del problema.