Предупреждение компилятора «Нет новой строки в конце файла» - PullRequest
178 голосов
/ 16 сентября 2008

В чем причина следующего предупреждения в некоторых компиляторах C ++?

Нет новой строки в конце файла

Почему у меня должна быть пустая строка в конце исходного / заголовочного файла?

Ответы [ 11 ]

207 голосов
/ 16 сентября 2008

Подумайте о некоторых проблемах, которые могут возникнуть при отсутствии новой строки. В соответствии со стандартом ANSI #include файла в начале вставляет файл точно так, как он находится в начале файла, и не вставляет новую строку после #include <foo.h> после содержимого файла. Таким образом, если вы добавите в парсер файл без новой строки в конце, он будет выглядеть так, как будто последняя строка foo.h находится на той же строке, что и первая строка foo.cpp. Что если последняя строка в foo.h была комментарием без новой строки? Теперь первая строка foo.cpp закомментирована. Это всего лишь пара примеров типов проблем, которые могут возникнуть.


Просто хотел указать всем заинтересованным сторонам на ответ Джеймса ниже. Хотя приведенный выше ответ все еще корректен для C, новый стандарт C ++ (C ++ 11) был изменен, так что это предупреждение больше не должно появляться, если используется C ++ и компилятор, соответствующий C ++ 11.

Из стандарта C ++ 11 через сообщение Джеймса:

Исходный файл, который не является пустым и не оканчивается символом новой строки или заканчивается символом новой строки, которому непосредственно предшествует символ обратной косой черты, прежде чем произойдет любое такое соединение, должен обрабатываться так, как если бы дополнительные символы новой строки были добавлены в файл (C ++ 11 §2.2 / 1).

42 голосов
/ 17 ноября 2011

Требование, чтобы каждый исходный файл заканчивался не экранированным символом новой строки, было удалено в C ++ 11. Спецификация теперь гласит:

Исходный файл, который не является пустым и не заканчивается символом новой строки или заканчивается символом новой строки, которому непосредственно предшествует символ обратной косой черты, прежде чем произойдет любое такое соединение, должен обрабатываться, как если бы дополнительные символы новой строки были добавлены в файл (C ++ 11 §2.2 / 1).

Соответствующий компилятор больше не должен выдавать это предупреждение (по крайней мере, при компиляции в режиме C ++ 11, если у компилятора есть режимы для разных ревизий спецификации языка).

24 голосов
/ 16 сентября 2008

C ++ 03 Standard [2.1.1.2] объявляет:

... Если исходный файл, который не пуст, не заканчивается символом новой строки или заканчивается символом новой строки непосредственно перед символом обратной косой черты, прежде чем произойдет любое такое соединение, поведение не определено.

15 голосов
/ 16 сентября 2008

Ответ для «послушного» - «потому что стандарт C ++ 03 говорит, что поведение программы, не заканчивающейся переводом строки, не определено» (перефразировано).

Ответ для любопытных здесь: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html.

6 голосов
/ 16 сентября 2008

Это не относится к пустой строке, а завершается ли последняя строка (которая может содержать содержимое) новой строкой.

Большинство текстовых редакторов помещают новую строку в конец последней строки файла, поэтому, если в последней строке ее нет, существует риск, что файл был усечен. Однако есть веские причины, по которым вам может не понадобиться перевод строки, поэтому это всего лишь предупреждение, а не ошибка.

5 голосов
/ 16 сентября 2008

#include заменит свою строку буквальным содержимым файла. Если файл не заканчивается новой строкой, строка, содержащая #include, которая его вытащила, объединится со следующей строкой.

2 голосов
/ 06 августа 2015

Поскольку поведение отличается в версиях C / C ++, если файл не заканчивается новой строкой. Особенно неприятны старые C ++ - версии, fx в C ++ 03 стандарт говорит (фазы перевода):

Если исходный файл, который не является пустым, не заканчивается новой строкой или заканчивается символом новой строки, которому непосредственно предшествует символ обратной косой черты, поведение не определено.

Неопределенное поведение - это плохо: стандартный компилятор, отвечающий требованиям, может делать здесь более или менее то, что он хочет (вставлять вредоносный код или что-то еще) - явно причина для предупреждения.

Хотя в C ++ 11 ситуация лучше, рекомендуется избегать ситуаций, когда поведение не определено в более ранних версиях. Спецификация C ++ 03 хуже, чем C99, которая прямо запрещает такие файлы (затем определяется поведение).

2 голосов
/ 23 декабря 2014

Конечно, на практике каждый компилятор добавляет новую строку после #include. К счастью. - @ mxcl

не конкретный C / C ++, а диалект C: при использовании расширения GL_ARB_shading_language_include компилятор glsl в OS X предупреждает вас NOT об отсутствии новой строки. Таким образом, вы можете написать MyHeader.h файл с защитой заголовка, который заканчивается на #endif // __MY_HEADER_H__, и вы потеряете строку после #include "MyHeader.h" наверняка.

2 голосов
/ 11 декабря 2012

Я использую c-free IDE версии 5.0, в моей программе на языке 'c ++' или 'c' у меня возникла та же проблема. Просто в конце программы т.е. последняя строка программа (после скобок функции это может быть основная или любая функция), нажмите ввод -линейный номер. будет увеличен на 1. затем выполнить ту же программу, она будет работать без ошибок.

0 голосов
/ 07 января 2012

Это предупреждение может также помочь указать, что файл мог быть как-то урезан. Это правда, что компилятор, вероятно, все равно выдаст ошибку компилятора - особенно если она находится в середине функции - или, возможно, ошибку компоновщика, но они могут быть более загадочными и не гарантированно произойдут.

Конечно, это предупреждение также не гарантируется, если файл обрезается сразу после новой строки, но оно все равно может отлавливать некоторые случаи, которые могут пропустить другие ошибки, и дает более сильный намек на проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...