Untuk konteks, saya adalah pengembang Dentang yang bekerja di Google. Di Google, kami telah meluncurkan diagnostik Clang ke (pada dasarnya) semua pengembang C ++ kami, dan kami memperlakukan peringatan Clang sebagai kesalahan juga. Sebagai pengembang Clang dan salah satu pengguna yang lebih besar dalam diagnosa Clang, saya akan mencoba memberi tanda pada flag-flag ini dan bagaimana mereka dapat digunakan. Perhatikan bahwa semua yang saya jelaskan secara umum berlaku untuk Dentang, dan tidak khusus untuk C, C ++, atau Objective-C.
TL; Versi DR: Silakan gunakan -Wall
dan -Werror
minimal pada kode baru yang Anda kembangkan. Kami (pengembang kompiler) menambahkan peringatan di sini untuk alasan yang baik: mereka menemukan bug. Jika Anda menemukan peringatan yang menangkap bug, nyalakan juga. Cobalah -Wextra
untuk sekelompok kandidat yang baik di sini. Jika salah satu dari mereka terlalu berisik untuk Anda manfaatkan, ajukan bug . Jika Anda menulis kode yang mengandung bug "jelas" tetapi kompiler tidak memperingatkannya, ajukan bug.
Sekarang untuk versi panjang. Pertama beberapa latar belakang pengelompokan bendera peringatan. Ada banyak "pengelompokan" peringatan di Dentang (dan sampai batas tertentu dalam GCC). Beberapa yang relevan dengan diskusi ini:
- On-by-default: Peringatan ini selalu aktif kecuali Anda menonaktifkannya secara eksplisit.
-Wall
: Ini adalah peringatan bahwa pengembang memiliki kepercayaan yang tinggi dalam nilai mereka dan tingkat false-positive yang rendah.
-Wextra
: Ini adalah peringatan yang diyakini bernilai dan masuk akal (yaitu, mereka tidak bermasalah), tetapi mereka mungkin memiliki tingkat positif palsu yang tinggi atau keberatan filosofis yang umum.
-Weverything
: Ini adalah kelompok gila yang secara harfiah memungkinkan setiap
peringatan di Dentang. Jangan gunakan ini pada kode Anda. Ini dimaksudkan hanya untuk pengembang Dentang atau untuk mengeksplorasi peringatan apa yang ada .
Ada dua kriteria utama yang disebutkan di atas yang memandu ke mana peringatan berada di Dentang, dan mari kita perjelas apa arti sebenarnya. Yang pertama adalah potensi
nilai dari kejadian tertentu peringatan. Ini adalah manfaat yang diharapkan ke pengguna (developer) ketika kebakaran peringatan dan benar
mengidentifikasi masalah dengan kode.
Kriteria kedua adalah ide laporan positif palsu . Ini adalah situasi di mana peringatan menyala pada kode, tetapi potensi masalah yang dikutip sebenarnya tidak terjadi karena konteks atau kendala lain dari program. Kode yang diperingatkan sebenarnya berperilaku dengan benar. Ini sangat buruk ketika peringatan itu tidak pernah dimaksudkan untuk menembak pada pola kode itu. Sebaliknya, itu adalah kekurangan dalam implementasi peringatan yang menyebabkannya memecat di sana.
Untuk peringatan Dentang, nilainya harus dalam hal kebenaran , bukan dalam hal gaya, selera, atau konvensi pengkodean. Ini membatasi seperangkat peringatan yang tersedia, menghalangi peringatan yang sering diminta seperti peringatan setiap kali {}
s tidak digunakan di sekitar badan if
pernyataan. Dentang juga sangat tidak toleran terhadap kesalahan positif . Tidak seperti kebanyakan kompiler lain, ia akan menggunakan berbagai sumber informasi yang luar biasa untuk memangkas positif palsu termasuk ejaan yang tepat dari konstruk, ada atau tidak adanya ekstra '()', gips, atau bahkan makro preprosesor!
Sekarang mari kita ambil beberapa contoh peringatan dunia nyata dari Dentang, dan lihat bagaimana mereka dikategorikan. Pertama, peringatan default-on:
% nl x.cc
1 class C { const int x; };
% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
^
1 warning generated.
Di sini tidak diperlukan bendera untuk mendapatkan peringatan ini. Alasannya adalah bahwa ini adalah kode tidak pernah benar-benar benar, memberikan tinggi peringatan nilai , dan peringatan hanya kebakaran pada kode yang dentang dapat membuktikan jatuh ke dalam ember ini, memberikan nol positif palsu tingkat.
% nl x2.cc
1 int f(int x_) {
2 int x = x;
3 return x;
4 }
% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
1 warning generated.
Dentang membutuhkan -Wall
bendera untuk peringatan ini. Alasannya adalah bahwa ada sejumlah kode non-sepele di luar sana yang telah menggunakan (baik atau buruk) pola kode yang kita tegaskan untuk secara sengaja menghasilkan nilai yang tidak diinisialisasi. Secara filosofis, saya melihat tidak ada gunanya dalam hal ini, tetapi banyak orang lain tidak setuju dan kenyataan perbedaan pendapat ini adalah yang mendorong peringatan di bawah
-Wall
bendera. Ini masih memiliki nilai yang sangat tinggi dan tingkat false-positive yang sangat rendah
, tetapi pada beberapa basis kode itu adalah non-starter.
% nl x3.cc
1 void g(int x);
2 void f(int arr[], unsigned int size) {
3 for (int i = 0; i < size; ++i)
4 g(arr[i]);
5 }
% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for (int i = 0; i < size; ++i)
~ ^ ~~~~
1 warning generated.
Peringatan ini membutuhkan -Wextra
bendera. Alasannya adalah bahwa ada
basis kode yang sangat besar di mana tanda yang tidak cocok pada perbandingan sangat umum. Meskipun peringatan ini memang menemukan beberapa bug, kemungkinan kode menjadi bug ketika pengguna menulisnya cukup rendah. Hasilnya adalah tingkat false-positive yang sangat tinggi . Namun, ketika ada bug dalam sebuah program karena aturan promosi yang aneh, seringkali sangat halus membuat peringatan ini
ketika menandai bug memiliki nilai yang relatif tinggi . Sebagai konsekuensinya, Clang menyediakannya dan mengeksposnya di bawah bendera.
Biasanya, peringatan tidak hidup lama di luar -Wextra
bendera. Dentang berusaha sangat keras untuk tidak menerapkan peringatan yang tidak melihat penggunaan dan pengujian reguler. Peringatan tambahan yang dihidupkan -Weverything
biasanya peringatan dalam pengembangan aktif atau dengan bug aktif. Entah itu akan diperbaiki dan ditempatkan di bawah bendera yang sesuai, atau harus dihapus.
Sekarang kita memiliki pemahaman tentang bagaimana hal-hal ini bekerja dengan Dentang, mari kita coba kembali ke pertanyaan awal: peringatan apa yang harus Anda nyalakan untuk perkembangan Anda? Sayangnya, jawabannya tergantung. Pertimbangkan pertanyaan-pertanyaan berikut untuk membantu menentukan peringatan apa yang paling cocok untuk situasi Anda.
- Apakah Anda memiliki kendali atas semua kode Anda, atau sebagian darinya eksternal?
- Apa tujuanmu? Menangkap bug, atau menulis kode yang lebih baik?
- Apa toleransi positif palsu Anda? Apakah Anda bersedia menulis kode tambahan untuk membungkam peringatan secara teratur?
Pertama dan terpenting, jika Anda tidak mengontrol kode, jangan coba mengubah peringatan tambahan di sana. Bersiaplah untuk mematikan beberapa. Ada banyak kode buruk di dunia, dan Anda mungkin tidak dapat memperbaikinya. Itu tidak apa-apa. Berusahalah untuk menemukan cara memfokuskan upaya Anda pada kode yang Anda kontrol.
Selanjutnya, cari tahu apa yang Anda inginkan dari peringatan Anda. Ini berbeda untuk orang yang berbeda. Dentang akan mencoba untuk memperingatkan tanpa opsi apa pun pada bug yang mengerikan, atau pola kode yang kita punya preseden historis lama yang menunjukkan tingkat bug sangat tinggi. Dengan mengaktifkan -Wall
Anda akan mendapatkan serangkaian peringatan yang jauh lebih agresif yang ditargetkan untuk menangkap kesalahan paling umum yang telah diamati pengembang Dentang dalam kode C ++. Tetapi dengan kedua hal ini tingkat
false-positive harus tetap cukup rendah.
Akhirnya, jika Anda benar-benar mau membungkam * false-positive * s di setiap kesempatan, lakukan -Wextra
. Mengarungi bug jika Anda melihat peringatan yang menangkap banyak bug nyata, tetapi yang memiliki kesalahan positif konyol atau tidak berguna. Kami terus bekerja untuk menemukan cara untuk membawa lebih banyak dan lebih dari logika bug-menemukan hadir di -Wextra
dalam -Wall
mana kita dapat menghindari false-positif.
Banyak yang akan menemukan bahwa tidak ada opsi ini yang tepat untuk mereka. Di Google, kami -Wall
mematikan beberapa peringatan karena banyak kode yang ada yang melanggar peringatan. Kami juga telah mengaktifkan beberapa peringatan secara eksplisit, meskipun peringatan itu tidak diaktifkan oleh -Wall
, karena mereka memiliki nilai yang sangat tinggi bagi kami. Jarak tempuh Anda akan bervariasi, tetapi kemungkinan akan bervariasi dengan cara yang sama. Sering kali lebih baik mengaktifkan beberapa peringatan utama daripada semuanya
-Wextra
.
Saya akan mendorong semua orang untuk mengaktifkan -Wall
kode non-legacy. Untuk kode baru, peringatan di sini hampir selalu berharga, dan benar-benar membuat pengalaman mengembangkan kode lebih baik. Sebaliknya, saya akan mendorong semua orang untuk
tidak mengaktifkan bendera di luar -Wextra
. Jika Anda menemukan peringatan dentang yang -Wextra
tidak termasuk tapi yang membuktikan sekali berharga untuk Anda, hanya file bug dan kami mungkin bisa meletakkannya di bawah -Wextra
. Apakah Anda secara eksplisit mengaktifkan beberapa himpunan bagian dari peringatan -Wextra
akan sangat bergantung pada kode Anda, gaya pengkodean Anda, dan apakah mempertahankan daftar itu lebih mudah daripada memperbaiki semua yang tidak ditemukan oleh -Wextra
.
Dari daftar peringatan OP (yang mencakup keduanya -Wall
dan -Wextra
) hanya peringatan berikut ini yang tidak dicakup oleh kedua kelompok (atau diaktifkan secara default). Kelompok pertama menekankan mengapa terlalu mengandalkan bendera peringatan eksplisit bisa buruk: tidak ada yang bahkan diterapkan di Dentang! Mereka diterima di baris perintah hanya untuk kompatibilitas GCC.
-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
Ember berikutnya dari peringatan yang tidak perlu dalam daftar asli adalah yang berlebihan dengan yang lain dalam daftar itu:
-Wformat-nonliteral
-- Bagian dari -Wformat=2
-Wshorten-64-to-32
-- Bagian dari -Wconversion
-Wsign-conversion
-- Bagian dari -Wconversion
Ada juga pilihan peringatan yang berbeda secara kategoris. Ini berurusan dengan varian dialek bahasa daripada dengan kode buggy atau non-buggy. Dengan pengecualian -Wwrite-strings
, ini semua adalah peringatan untuk ekstensi bahasa yang disediakan oleh Dentang. Apakah Dentang memperingatkan tentang penggunaannya tergantung pada prevalensi ekstensi. Dentang bertujuan untuk kompatibilitas GCC, dan dalam banyak kasus memudahkannya dengan ekstensi bahasa implisit yang digunakan secara luas. -Wwrite-strings
, seperti yang dikomentari pada OP, adalah flag kompatibilitas dari GCC yang benar-benar mengubah semantik program. Saya sangat menyesali bendera ini, tetapi kami harus mendukungnya karena warisan yang dimilikinya sekarang.
-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
Opsi yang tersisa yang sebenarnya mengaktifkan peringatan yang berpotensi menarik adalah:
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
Alasan mengapa ini tidak ada -Wall
atau -Wextra
tidak selalu jelas. Bagi banyak dari ini, mereka benar-benar didasarkan pada peringatan GCC ( -Wconversion
,
-Wshadow
, dll) dan sebagai dentang seperti mencoba untuk meniru perilaku GCC. Kami perlahan memecah beberapa dari ini menjadi peringatan yang lebih baik dan berguna. Mereka kemudian memiliki kemungkinan lebih tinggi untuk masuk ke dalam salah satu kelompok peringatan tingkat atas. Yang mengatakan, untuk memilih pada satu peringatan, -Wconversion
adalah begitu luas sehingga kemungkinan akan tetap sendiri "tingkat atas" kategori di masa mendatang. Beberapa peringatan lain yang dimiliki GCC tetapi memiliki nilai rendah dan tingkat false-positive yang tinggi dapat diturunkan ke tanah tak bertuan yang serupa.
Alasan lain mengapa ini tidak termasuk dalam salah satu ember besar termasuk bug sederhana, masalah positif palsu yang sangat signifikan, dan peringatan dalam pengembangan. Saya akan melihat bug pengarsipan untuk hal-hal yang dapat saya identifikasi. Mereka semua akhirnya harus bermigrasi ke bendera ember besar yang tepat atau dihapus dari Dentang.
Saya harap ini menjelaskan situasi peringatan dengan Dentang dan memberikan beberapa wawasan bagi mereka yang mencoba untuk memilih satu set peringatan untuk penggunaan mereka, atau penggunaan perusahaan mereka.