Opsi g ++ -Wall termasuk -Wreorder. Apa yang dilakukan opsi ini dijelaskan di bawah ini. Tidak jelas bagi saya mengapa seseorang peduli (terutama cukup untuk mengaktifkannya secara default di -Dinding).
-Wreorder (Khusus C ++) Peringatkan ketika urutan inisialisasi anggota yang diberikan dalam kode tidak cocok dengan urutan di mana mereka harus dieksekusi. Misalnya: struct A { int i; int j; A (): j (0), i (1) {} }; Kompiler akan mengatur ulang inisialisasi anggota untuk i dan j menjadi cocok dengan perintah deklarasi anggota, memancarkan peringatan untuk itu efek. Peringatan ini diaktifkan oleh -Wall.
c++
g++
compiler-warnings
Peeter Joot
sumber
sumber
-Werror=reorder
Jawaban:
Mempertimbangkan:
Sekarang
i
diinisialisasi ke beberapa nilai yang tidak diketahui, bukan nol.Atau, inisialisasi
i
mungkin memiliki beberapa efek samping yang urutannya penting. Misalnyasumber
i
diinisialisasi ke1
). Di sini,i
diinisialisasij
, yang sebenarnya menunjukkan masalah.Masalahnya adalah seseorang mungkin melihat daftar inisialisasi anggota di konstruktor, dan berpikir bahwa mereka dieksekusi dalam urutan itu (j pertama, lalu saya). Mereka tidak, mereka dieksekusi dalam urutan anggota didefinisikan di kelas.
Misalkan Anda menulis
A(): j(0), i(j) {}
. Seseorang mungkin membaca itu, dan berpikir bahwa saya berakhir dengan nilai 0. Tidak, karena Anda menginisialisasinya dengan j, yang berisi sampah karena itu sendiri belum diinisialisasi.Peringatan itu mengingatkan Anda untuk menulis
A(): i(j), j(0) {}
, yang semoga terlihat jauh lebih mencurigakan.sumber
Jawaban lain telah memberikan beberapa contoh bagus yang membenarkan pilihan untuk peringatan. Saya pikir saya akan memberikan beberapa konteks sejarah. Pencipta C ++, Bjarne Stroustrup, menjelaskan dalam bukunya The C ++ language programming (edisi ke-3, Halaman 259):
sumber
Ini dapat menggigit Anda jika inisialisasi Anda memiliki efek samping. Mempertimbangkan:
Di atas akan mencetak "bilah" lalu "foo", meskipun secara intuitif orang akan menganggap bahwa urutan seperti yang tertulis dalam daftar penginisialisasi.
Atau, jika
x
dany
dari beberapa tipe yang ditentukan pengguna dengan konstruktor, konstruktor itu mungkin juga memiliki efek samping, dengan hasil yang tidak jelas sama.Itu juga dapat memanifestasikan dirinya ketika penginisialisasi untuk satu anggota referensi anggota lain.
sumber
Peringatan ada karena jika Anda baru saja membaca konstruktor, sepertinya
j
sudah diinisialisasi sebelumnyai
. Ini menjadi masalah jika satu digunakan untuk menginisialisasi yang lain, seperti padaKetika Anda hanya melihat konstruktor, ini terlihat aman. Namun pada kenyataannya,
j
belum diinisialisasi pada titik di mana ia digunakan untuk menginisialisasii
, sehingga kode tidak akan berfungsi seperti yang diharapkan. Karena itu peringatan.sumber