it-swarm-id.com

Peringatan kompiler "Tidak ada baris baru di akhir file"

Apa alasan untuk peringatan berikut di beberapa kompiler C++?

Tidak ada baris baru di akhir file

Mengapa saya harus memiliki baris kosong di akhir file sumber/header?

180
LeChuck2k

Pikirkan beberapa masalah yang dapat terjadi jika tidak ada baris baru. Menurut standar ANSI, #include dari sebuah file di awal menyisipkan file persis seperti di bagian depan file dan tidak memasukkan baris baru setelah #include <foo.h> setelah konten file . Jadi jika Anda menyertakan file tanpa baris baru di akhir parser, file tersebut akan dilihat seolah-olah baris terakhir foo.h berada di baris yang sama dengan baris pertama foo.cpp. Bagaimana jika baris terakhir foo.h adalah komentar tanpa baris baru? Sekarang baris pertama foo.cpp dikomentari. Ini hanya beberapa contoh dari jenis masalah yang dapat merambah.


Hanya ingin menunjukkan pihak yang berkepentingan terhadap jawaban James di bawah ini. Sementara jawaban di atas masih benar untuk C, standar C++ baru (C++ 11) telah diubah sehingga peringatan ini tidak lagi dikeluarkan jika menggunakan C++ dan kompiler yang sesuai dengan C++ 11.

Dari standar C++ 11 melalui pos James:

File sumber yang tidak kosong dan yang tidak diakhiri dengan karakter baris baru, atau yang berakhir dengan karakter baris baru segera didahului oleh karakter backslash sebelum terjadi penyambungan seperti itu, harus diproses seolah-olah ada tambahan baru karakter baris ditambahkan ke file (C++ 11 §2.2/1).

210
TJ Seabrooks

Persyaratan bahwa setiap file sumber berakhir dengan baris baru yang tidak terhapus telah dihapus dalam C++ 11. Spesifikasi sekarang berbunyi:

File sumber yang tidak kosong dan yang tidak diakhiri dengan karakter baris baru, atau yang berakhir dengan karakter baris baru segera didahului oleh karakter backslash sebelum terjadi penyambungan seperti itu, harus diproses seolah-olah ada tambahan baru karakter baris ditambahkan ke file (C++ 11 §2.2/1).

Compiler yang menyesuaikan tidak perlu lagi mengeluarkan peringatan ini (setidaknya tidak ketika mengkompilasi dalam mode C++ 11, jika kompiler memiliki mode untuk revisi yang berbeda dari spesifikasi bahasa).

42
James McNellis

C++ 03 Standard [2.1.1.2] menyatakan:

... Jika file sumber yang tidak kosong tidak berakhir pada karakter baris baru, atau berakhir pada karakter baris baru segera didahului oleh karakter backslash sebelum terjadi penyambungan, perilaku tersebut tidak ditentukan.

24
Igor Semenov

Jawaban untuk "patuh" adalah "karena Standar C++ 03 mengatakan perilaku suatu program yang tidak berakhir pada baris baru tidak ditentukan" (diparafrasekan).

Jawaban bagi yang penasaran ada di sini: http://gcc.gnu.org/ml/gcc/2001-07/msg01120.html .

15

Itu tidak merujuk ke baris kosong, itu adalah apakah baris terakhir (yang dapat memiliki konten di dalamnya) diakhiri dengan baris baru.

Kebanyakan editor teks akan meletakkan baris baru di akhir baris terakhir file, jadi jika baris terakhir tidak memilikinya, ada risiko file tersebut telah terpotong. Namun, ada alasan yang sah mengapa Anda mungkin tidak ingin baris baru jadi itu hanya peringatan, bukan kesalahan.

6
Leigh Caldwell

#include akan mengganti barisnya dengan konten literal dari file tersebut. Jika file tidak diakhiri dengan baris baru, baris yang berisi #include yang menariknya akan bergabung dengan baris berikutnya.

5
moonshadow

Tentu saja dalam praktiknya setiap kompiler menambahkan baris baru setelah #include. Untungnya - @mxcl

bukan C/C++ spesifik tetapi dialek C: ketika menggunakan ekstensi GL_ARB_shading_language_include compiler glsl pada OS X memperingatkan Anda BUKAN tentang baris baru yang hilang. Jadi Anda dapat menulis file MyHeader.h dengan pelindung kepala yang diakhiri dengan #endif // __MY_HEADER_H__ dan Anda akan kehilangan garis setelah #include "MyHeader.h" pasti.

2
Jan-Philip Loos

Karena perilaku berbeda antara versi C/C++ jika file tidak berakhir dengan baris baru. Terutama nasty adalah versi C++ - yang lebih lama, fx dalam C++ 03 kata standar (fase terjemahan):

Jika file sumber yang tidak kosong tidak diakhiri dengan karakter baris baru, atau diakhiri dengan karakter baris baru segera didahului oleh karakter backslash, perilaku tidak terdefinisi.

Perilaku tidak terdefinisi buruk: kompiler penyesuai standar dapat melakukan lebih atau kurang apa yang diinginkannya di sini (masukkan kode jahat atau apa pun) - jelas alasan peringatan.

Meskipun situasinya lebih baik di C++ 11, adalah ide yang baik untuk menghindari situasi di mana perilaku tidak terdefinisi dalam versi sebelumnya. Spesifikasi C++ 03 lebih buruk daripada C99 yang langsung melarang file tersebut (perilaku kemudian didefinisikan).

2
skyking

Saya menggunakan c-free IDE versi 5.0, dalam program saya baik bahasa 'c ++' atau 'c' saya mendapatkan masalah yang sama. Hanya pada akhir program ie baris terakhir dari program (setelah kawat gigi fungsi mungkin fungsi utama atau apa saja), tekan enter - no baris. akan bertambah 1. kemudian jalankan program yang sama, itu akan berjalan tanpa kesalahan.

2
divesh

Peringatan ini mungkin juga membantu untuk menunjukkan bahwa suatu file bisa saja terpotong. Memang benar bahwa kompiler mungkin akan melemparkan kesalahan kompiler - terutama jika itu di tengah fungsi - atau mungkin kesalahan linker, tetapi ini bisa lebih samar, dan tidak dijamin akan terjadi.

Tentu saja peringatan ini juga tidak dijamin jika file terpotong segera setelah baris baru, tetapi masih bisa menangkap beberapa kasus bahwa kesalahan lain mungkin terlewatkan, dan memberikan petunjuk yang lebih kuat untuk masalah ini.

0
mwfearnley