Seringkali di C di bawah gcc
, saya akan mulai dengan serangkaian tanda peringatan berikut (dirakit dengan menyakitkan dari berbagai sumber):
-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi
Saya akan membangun (setidaknya versi debug saya) dengan rangkaian peringatan ini dan memperbaiki semua yang saya bisa (biasanya semuanya), dan kemudian hanya menghapus tanda jika tidak relevan atau tidak dapat diperbaiki (hampir tidak pernah terjadi). Kadang-kadang, saya juga akan menambahkan -Werror
jika saya harus menjauh saat menyusun.
Saya baru saja mengambil C ++ (ya, saya 15 tahun ketinggalan zaman), dan saya ingin memulai dengan langkah yang benar.
Pertanyaan saya adalah: Apakah seseorang memiliki kumpulan peringatan lengkap serupa yang telah dikompilasi sebelumnya untuk C ++ di bawah g++
? (Saya tahu banyak dari mereka akan sama.)
-Wall
) adalah-Wbloody_everything
bendera :-)-Weverything
. Saya telah membaca bahwa bahkan pengembang Clang ++ sedikit khawatir tentang pengguna yang mengaktifkannya; rupanya itu dimaksudkan untuk penggunaan pengembangan internal saja. Ini tidak masuk akal, karena menyalakan-Weverything
mungkin adalah cara terbaik untuk menemukan peringatan yang berpotensi membantu yang tidak Anda ketahui sebelumnya.Jawaban:
Saya memeriksa dan menemukan set minimal yang harus mendapatkan tingkat peringatan maksimum. Saya kemudian menghapus dari daftar itu serangkaian peringatan yang saya rasa tidak benar-benar menunjukkan sesuatu yang buruk sedang terjadi, atau memiliki terlalu banyak positif palsu untuk digunakan dalam membangun nyata. Saya berkomentar mengapa masing-masing yang saya kecualikan dikecualikan. Ini adalah rangkaian peringatan terakhir yang saya sarankan:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
Peringatan dipertanyakan yang ada:
Saya menyertakan
-Wno-unused
karena saya sering memiliki variabel yang saya tahu akan saya gunakan nanti, tetapi belum memiliki fungsionalitas yang ditulis untuk. Menghapus peringatan tentang itu memungkinkan saya untuk menulis dalam gaya yang saya sukai sesekali menunda implementasi sesuatu. Berguna untuk mematikannya sesekali untuk memastikan tidak ada yang lolos dari celah.-Wdisabled-optimization
sepertinya pengaturan preferensi pengguna yang kuat. Saya baru saja menambahkan yang ini ke build saya (hanya untuk build yang dioptimalkan untuk alasan yang jelas) dan tidak menghasilkan apa-apa, jadi sepertinya bukan peringatan yang cerewet, setidaknya untuk cara saya membuat kode. Saya memasukkannya (meskipun kode yang memicu peringatan ini tidak selalu salah) karena saya percaya dalam bekerja dengan alat saya alih-alih melawannya. Jika gcc memberi tahu saya bahwa ia tidak dapat mengoptimalkan kode untuk cara saya menulisnya, maka saya harus melihat untuk menulis ulang. Saya curiga bahwa kode yang memicu peringatan ini dapat mengambil manfaat dari menjadi lebih modular, terlepas dari itu, jadi meskipun kode tersebut secara teknis tidak salah (mungkin), secara gaya memang demikian.-Wfloat-equal
memperingatkan untuk perbandingan kesetaraan yang aman (khususnya, perbandingan dengan nilai yang tidak dihitung -1). Contoh dalam kode saya di mana saya menggunakan ini adalah bahwa saya memiliki vektor float. Saya membahas vektor ini, dan ada beberapa elemen yang belum dapat saya evaluasi apa yang seharusnya, jadi saya menetapkannya ke -1.0f (karena masalah saya hanya menggunakan bilangan positif, -1 di luar domain). Saya kemudian pergi melalui dan memperbarui nilai -1.0f. Itu tidak dengan mudah meminjamkan dirinya ke metode operasi yang berbeda. Saya menduga bahwa kebanyakan orang tidak memiliki masalah ini, dan perbandingan angka pasti dalam floating point mungkin merupakan kesalahan, jadi saya memasukkannya ke dalam daftar default.-Wold-style-cast
memiliki banyak positif palsu dalam kode perpustakaan yang saya gunakan. Secara khusus, keluarga fungsi htonl yang digunakan dalam jaringan, serta implementasi enkripsi Rijndael (AES) yang saya gunakan memiliki cast gaya lama yang mengingatkan saya. Saya bermaksud untuk mengganti keduanya, tetapi saya tidak yakin apakah ada hal lain dalam kode saya yang akan dikeluhkan. Sebagian besar pengguna mungkin harus mengaktifkan ini secara default.-Wsign-conversion
adalah yang sulit (dan hampir tidak masuk daftar). Mengaktifkannya di kode saya menghasilkan sejumlah besar peringatan (100+). Hampir semuanya tidak bersalah. Namun, saya telah berhati-hati untuk menggunakan bilangan bulat yang ditandatangani di mana pun saya tidak yakin, meskipun untuk domain masalah khusus saya, saya biasanya akan mendapatkan sedikit peningkatan efisiensi menggunakan nilai yang tidak ditandatangani karena banyaknya pembagian bilangan bulat yang saya lakukan. Saya mengorbankan efisiensi ini karena saya khawatir tentang secara tidak sengaja mempromosikan bilangan bulat bertanda ke unsigned dan kemudian membagi (yang tidak aman, tidak seperti penambahan, pengurangan, dan perkalian). Mengaktifkan peringatan ini memungkinkan saya mengubah sebagian besar variabel saya dengan aman ke tipe unsigned dan menambahkan beberapa cast di beberapa tempat lain. Saat ini agak sulit digunakan karena peringatannya tidak terlalu pintar. Misalnya, jika Anda melakukannyaunsigned short + (integral constant expression)
, hasil tersebut secara implisit dipromosikan menjadi int. Kemudian memperingatkan tentang potensi masalah tanda jika Anda menetapkan nilai itu keunsigned
atauunsigned short
, meskipun aman. Ini jelas merupakan peringatan paling opsional untuk hampir semua pengguna.-Wsign-promo
: lihat-Wsign-conversion
.-Wswitch-default
tampaknya tidak berguna (Anda tidak selalu menginginkan kasus default jika Anda telah menyebutkan semua kemungkinan secara eksplisit). Namun, mengaktifkan peringatan ini dapat memberlakukan sesuatu yang mungkin merupakan ide bagus. Untuk kasus di mana Anda secara eksplisit ingin mengabaikan semuanya kecuali kemungkinan yang terdaftar (tetapi nomor lain dimungkinkan), masukkandefault: break;
untuk membuatnya eksplisit. Jika Anda secara eksplisit menghitung semua kemungkinan, mengaktifkan peringatan ini akan membantu memastikan bahwa Anda memasukkan sesuatu seperti assert (false) untuk memastikan bahwa Anda telah benar-benar mencakup semua opsi yang memungkinkan. Ini memungkinkan Anda untuk secara eksplisit tentang apa domain masalah Anda dan secara terprogram menerapkannya. Namun, Anda harus berhati-hati dalam hanya menempelkan assert (false) di mana-mana. Ini lebih baik daripada tidak melakukan apa pun dengan kasus default, tetapi seperti biasa dengan assert, ini tidak akan berfungsi dalam versi rilis. Dengan kata lain, Anda tidak dapat mengandalkannya untuk memvalidasi nomor yang Anda peroleh dari, katakanlah, koneksi jaringan atau database yang tidak dapat Anda kendalikan secara mutlak. Pengecualian atau pengembalian lebih awal adalah cara terbaik untuk menanganinya (tetapi tetap mengharuskan Anda memiliki kasus default!).-Werror
adalah yang penting bagi saya. Saat mengompilasi kode dalam jumlah besar dalam build multi-thread dengan beberapa target, peringatan akan mudah lewat. Mengubah peringatan menjadi kesalahan memastikan bahwa saya menyadarinya.Kemudian ada satu set peringatan yang tidak termasuk dalam daftar di atas karena menurut saya tidak berguna. Ini adalah peringatan dan komentar saya tentang mengapa saya tidak memasukkannya ke dalam daftar default:
Peringatan yang tidak ada:
-Wabi
tidak diperlukan karena saya tidak menggabungkan binari dari kompiler yang berbeda. Saya tetap mencoba mengompilasinya, dan tidak memicu, jadi sepertinya tidak bertele-tele.-Waggregate-return
bukanlah sesuatu yang saya anggap sebagai kesalahan. Misalnya, ini dipicu saat menggunakan for loop berbasis rentang pada vektor kelas. Pengoptimalan nilai kembali harus menangani semua efek negatif dari ini.-Wconversion
dipicu pada kode ini:short n = 0; n += 2;
Konversi implisit ke int menyebabkan peringatan saat dikonversi kembali ke jenis targetnya.-Weffc++
termasuk peringatan jika semua anggota data tidak diinisialisasi dalam daftar penginisialisasi. Saya sengaja tidak melakukan ini dalam banyak kasus, jadi rangkaian peringatan terlalu berantakan untuk bisa digunakan. Akan sangat membantu untuk mengaktifkannya sesekali dan memindai peringatan lain (seperti destruktor non-virtual dari kelas dasar). Ini akan lebih berguna sebagai kumpulan peringatan (seperti-Wall
) daripada satu peringatan saja.-Winline
tidak ada karena saya tidak menggunakan kata kunci inline untuk tujuan pengoptimalan, hanya untuk mendefinisikan fungsi inline di header. Saya tidak peduli jika pengoptimal benar-benar menyejajarkannya. Peringatan ini juga mengeluh jika tidak bisa sebaris fungsi yang dideklarasikan dalam badan kelas (seperti penghancur virtual kosong).-Winvalid-pch
hilang karena saya tidak menggunakan header yang telah dikompilasi sebelumnya.-Wmissing-format-attribute
tidak digunakan karena saya tidak menggunakan ekstensi gnu. Sama untuk-Wsuggest-attribute
dan beberapa lainnyaBerpotensi terkenal karena ketidakhadirannya
-Wno-long-long
, yang tidak saya butuhkan. Saya mengkompilasi dengan-std=c++0x
(-std=c++11
di GCC 4.7), yang menyertakanlong long
tipe integer. Mereka yang terjebak kembali pada C ++ 98 / C ++ 03 dapat mempertimbangkan untuk menambahkan pengecualian itu dari daftar peringatan.-Wnormalized=nfc
sudah menjadi opsi default, dan tampaknya yang terbaik.-Wpadded
diaktifkan sesekali untuk mengoptimalkan tata letak kelas, tetapi tidak dibiarkan karena tidak semua kelas memiliki cukup elemen untuk menghapus bantalan di bagian akhir. Secara teori saya bisa mendapatkan beberapa variabel tambahan secara 'gratis', tetapi itu tidak sebanding dengan upaya ekstra untuk mempertahankannya (jika ukuran kelas saya berubah, tidak mudah untuk menghapus variabel bebas yang sebelumnya).-Wstack-protector
tidak digunakan karena saya tidak menggunakan-fstack-protector
-Wstrict-aliasing=3
diaktifkan oleh-Wall
dan merupakan yang paling akurat, tetapi sepertinya level 1 dan 2 memberikan lebih banyak peringatan. Secara teori, level yang lebih rendah adalah peringatan yang 'lebih kuat', tetapi mengorbankan lebih banyak positif palsu. Kode pengujian saya sendiri terkompilasi dengan rapi di bawah semua 3 level.-Wswitch-enum
bukanlah perilaku yang saya inginkan. Saya tidak ingin menangani setiap pernyataan switch secara eksplisit. Akan berguna jika bahasa memiliki beberapa mekanisme untuk mengaktifkan ini pada pernyataan sakelar yang ditentukan (untuk memastikan bahwa perubahan masa depan pada enum ditangani di mana pun mereka perlu), tetapi itu berlebihan untuk pengaturan "semua atau tidak sama sekali".-Wunsafe-loop-optimizations
menyebabkan terlalu banyak peringatan palsu. Mungkin berguna untuk menerapkan yang satu ini secara berkala dan memverifikasi hasilnya secara manual. Sebagai contoh, ini menghasilkan peringatan ini dalam kode saya ketika saya mengulang semua elemen dalam vektor untuk menerapkan satu set fungsi ke mereka (menggunakan for loop berbasis rentang). Ini juga merupakan peringatan untuk konstruktor dari array const dari const std :: string (di mana ini bukan loop dalam kode pengguna).-Wzero-as-null-pointer-constant
dan-Wuseless-cast
merupakan peringatan khusus GCC 4.7, yang akan saya tambahkan saat saya bertransisi ke GCC 4.7.Saya telah mengajukan beberapa laporan bug / permintaan peningkatan di gcc sebagai hasil dari beberapa penelitian ini, jadi semoga pada akhirnya saya dapat menambahkan lebih banyak peringatan dari daftar "jangan sertakan" ke daftar "sertakan" . Daftar ini mencakup semua peringatan yang disebutkan di utas ini (ditambah saya pikir beberapa tambahan). Banyak dari peringatan yang tidak disebutkan secara eksplisit dalam posting ini dimasukkan sebagai bagian dari peringatan lain yang saya sebutkan. Jika ada yang memperhatikan peringatan apa pun yang dikecualikan dari posting ini sepenuhnya, beri tahu saya.
edit: Sepertinya saya telah melewatkan beberapa (yang sekarang telah saya tambahkan). Sebenarnya ada halaman kedua di http://gcc.gnu.org yang cukup tersembunyi. Opsi peringatan umum dan opsi C ++ (gulir ke bawah ke bawah untuk peringatan)
sumber
-Wswitch-enum
memperingatkan jika Anda tidak secara eksplisit menangani setiap nilai enumerasi dalam sebuah sakelar, dandefault
tidak dihitung sebagai eksplisit. Di sisi lain,-Wswitch-default
memperingatkan Anda jika sakelar Anda tidak memilikidefault
casing, meskipun Anda telah secara eksplisit mencakup semua kemungkinan nilai.-isystem
alih-alih-I
pada "kode perpustakaan lama" Anda untuk mencegah semua positif palsu ituDuh, semua pencarian asli saya menghasilkan 99% posting tentang cara menekan peringatan (cukup menakutkan), tetapi saya baru saja menemukan komentar ini , yang memiliki kumpulan bendera yang indah ini (beberapa kurang relevan):
Periksa silang dengan:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Jadi, saya pikir itu titik awal yang bagus. Tidak menyadari ini adalah penipuan, tapi setidaknya itu terkubur dalam-dalam. :-)
sumber
-Wall
tidak melakukan apa yang diharapkan. Tapi terima kasih, beberapa di antaranya terlihat sangat berguna!-Waggregate-return
? Ini memberi saya peringatan untuk setiap penggunaanbegin/end()
Beberapa di antaranya sudah termasuk dalam
-Wall
atau-Wextra
.Pengaturan dasar yang baik untuk C adalah:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror
dan untuk C ++
-ansi -pedantic -Wall -Wextra -Weffc++
(melewatkan
-Werror
C ++ karena-Weffc++
memiliki beberapa gangguan)sumber
-std=c89
. Dalam mode C ++, ini setara dengan-std=c++98
. yaitu jika Anda menentukan yang lainstd
, jangan gunakanansi
Mencoba
Itu awal yang cepat dan kotor yang pasti membutuhkan beberapa penyetelan; untuk satu hal, bahkan jika Anda memanggil kompilator dengan nama yang sesuai untuk bahasa Anda (misalnya
g++
untuk C ++), Anda akan mendapatkan peringatan yang tidak berlaku untuk bahasa itu (dan kompilator akan angkat tangan dan menolak untuk melanjutkan sampai Anda hapus peringatan).Hal lain adalah saya menambahkan
-Werror
, karena jika Anda tidak memperbaiki peringatan, mengapa Anda peduli untuk menyalakannya? Anda juga dapat mengeluarkan peringatan dari daftar. (Misalnya, saya hampir tidak pernah menggunakan-Waggregate-return
C ++.)Beberapa peringatan tidak akan melakukan apa pun tanpa opsi terkait kinerja lainnya (
-Wstack-protector
).-fdiagnostics-show-option
dan manual GCC adalah teman Anda.Ngomong-ngomong, beberapa peringatan bersifat eksklusif; secara khusus menggunakan
-Wtraditional
dan-Wold-style-definition
bersama-Werror
, tidak akan dikompilasi.sumber
Di CmakeLists.txt Clion saya
sumber