Quelle est la raison de l'avertissement suivant dans certains compilateurs C++?
Pas de nouvelle ligne en fin de fichier
Pourquoi devrais-je avoir une ligne vide à la fin d'un fichier source/en-tête?
Pensez à certains des problèmes qui peuvent survenir s’il n’ya pas de nouvelle ligne. Selon la norme ANSI, le #include
d’un fichier au début insère le fichier exactement comme il est au début du fichier et n’insère pas la nouvelle ligne après le #include <foo.h>
après le contenu du fichier. Donc, si vous incluez un fichier sans nouvelle ligne à la fin de l'analyseur, il sera vu comme si la dernière ligne de foo.h
est sur la même ligne que la première ligne de foo.cpp
. Et si la dernière ligne de foo.h était un commentaire sans nouvelle ligne? Maintenant la première ligne de foo.cpp
est commenté. Ce ne sont là que quelques exemples des types de problèmes qui peuvent surgir.
Je voulais juste indiquer aux parties intéressées la réponse de James ci-dessous. Bien que la réponse ci-dessus soit toujours correcte pour le langage C, le nouveau standard C++ (C++ 11) a été modifié afin que cet avertissement ne soit plus émis si vous utilisez C++ et un compilateur conforme à C++ 11.
Du standard C++ 11 via le post de James:
Un fichier source qui n'est pas vide et qui ne se termine pas par un caractère de nouvelle ligne, ou qui se termine par un caractère de nouvelle ligne immédiatement précédé d'un caractère de barre oblique inverse avant qu'un tel épissage ne se produise, doit être traité comme si un nouveau caractère supplémentaire était ajouté. caractère de ligne ont été ajoutés au fichier (C++ 11 §2.2/1).
L'exigence selon laquelle chaque fichier source doit se terminer par une nouvelle ligne non échappée a été supprimée dans C++ 11. La spécification se lit maintenant comme suit:
Un fichier source qui n'est pas vide et qui ne se termine pas par un caractère de nouvelle ligne, ou qui se termine par un caractère de nouvelle ligne immédiatement précédé d'un caractère de barre oblique inverse avant qu'un tel épissage ne se produise, doit être traité comme si un nouveau caractère supplémentaire était ajouté. caractère de ligne ont été ajoutés au fichier (C++ 11 §2.2/1).
Un compilateur conforme ne devrait plus émettre cet avertissement (du moins lors de la compilation en mode C++ 11, si le compilateur dispose de modes pour différentes révisions de la spécification de langage).
La norme C++ 03 [2.1.1.2] déclare:
... Si un fichier source non vide ne se termine pas par un caractère de nouvelle ligne, ni par un caractère de nouvelle ligne immédiatement précédé d'un caractère de barre oblique inversée avant qu'un tel épissage ne se produise, le comportement est indéfini.
La réponse pour "obéissant" est "parce que le standard C++ 03 dit que le comportement d'un programme ne se terminant pas par une nouvelle ligne n'est pas défini" (paraphrasé).
La réponse pour les curieux est la suivante: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .
Il ne fait pas référence à une ligne vide, mais à la question de savoir si la dernière ligne (pouvant contenir du contenu) est terminée par une nouvelle ligne.
La plupart des éditeurs de texte placent une nouvelle ligne à la fin de la dernière ligne d'un fichier. Par conséquent, si la dernière ligne n'en contient pas, le fichier risque d'être tronqué. Cependant, il existe des raisons valables pour lesquelles vous ne souhaitez peut-être pas utiliser la nouvelle ligne. Il ne s'agit donc que d'un avertissement, pas d'une erreur.
#include
remplacera sa ligne par le contenu littéral du fichier. Si le fichier ne se termine pas par une nouvelle ligne, la ligne contenant le #include
qui l'a tiré va fusionner avec la ligne suivante.
Bien sûr, dans la pratique, chaque compilateur ajoute une nouvelle ligne après le #include. Heureusement. - @mxcl
c/C++ non spécifique mais un dialecte C: lorsqu’on utilise le GL_ARB_shading_language_include
_ extension du compilateur glsl sur OS X vous avertit PAS à propos d'une nouvelle ligne manquante. Vous pouvez donc écrire un MyHeader.h
fichier avec une garde d'en-tête qui se termine par #endif // __MY_HEADER_H__
et vous perdrez perdez la ligne après le #include "MyHeader.h"
pour sûr.
Parce que le comportement diffère entre les versions C/C++ si le fichier ne se termine pas par une nouvelle ligne. Les versions les plus anciennes de C++ sont particulièrement désagréables, alors que la norme en f ++ en C++ 03 dit (phases de traduction):
Si un fichier source non vide ne se termine pas par un caractère de nouvelle ligne, ni par un caractère de nouvelle ligne immédiatement précédé d'un caractère de barre oblique inverse, le comportement est indéfini.
Un comportement indéfini est mauvais: un compilateur conforme standard peut faire plus ou moins ce qu'il veut ici (insérer du code malicieux ou autre) - un motif évident d'avertissement.
Bien que la situation soit meilleure en C++ 11, il est judicieux d'éviter les situations dans lesquelles le comportement n'est pas défini dans les versions antérieures. La spécification C++ 03 est pire que C99 qui interdit carrément de tels fichiers (le comportement est alors défini).
J'utilise c-free IDE version 5.0, dans mon programme, que ce soit en "c ++" ou en "c", la langue me posait le même problème.Juste à la fin du programme c'est-à-dire la dernière ligne du programme (après les accolades, il peut s'agir d'une fonction principale ou de n'importe quelle fonction), appuyez sur entrée - le numéro de ligne sera augmenté de 1. Ensuite, exécutez le même programme, il sera exécuté sans erreur.
Cet avertissement peut également aider à indiquer qu'un fichier peut avoir été tronqué d'une manière ou d'une autre. Il est vrai que le compilateur générera probablement une erreur, en particulier si elle est au milieu d'une fonction, ou peut-être une erreur de l'éditeur de liens, mais elle pourrait être plus cryptique et ne devrait pas se produire.
Bien entendu, cet avertissement n’est pas garanti non plus si le fichier est tronqué immédiatement après une nouvelle ligne, mais il peut toujours détecter certains cas que d’autres erreurs risquent de manquer et donner une indication plus précise du problème.