it-swarm-ru.tech

Предупреждение компилятора «Нет новой строки в конце файла»

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

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

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

178
LeChuck2k

Подумайте о некоторых проблемах, которые могут возникнуть при отсутствии новой строки. В соответствии со стандартом 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).

207
TJ Seabrooks

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

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

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

42
James McNellis

Стандарт C++ 03 [2.1.1.2] объявляет:

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

24
Igor Semenov

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

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

15
Vytautas Shaltenis

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

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

6
Leigh Caldwell

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

5
moonshadow

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

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

2
Jan-Philip Loos

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

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

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

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

2
skyking

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

2
divesh

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

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

0
mwfearnley