Fitur "Seluruh tim" C ++?


16

Di C ++, fitur-fitur seperti pengecualian memengaruhi seluruh program Anda: Anda bisa menonaktifkannya di seluruh program Anda , atau Anda perlu mengatasinya di seluruh kode Anda. Seperti artikel terkenal tentang C ++ Report menuliskannya:

Kontra-intuitif, bagian sulit dari pengkodean pengecualian bukanlah lemparan dan tangkapan eksplisit. Bagian yang sangat sulit dari menggunakan pengecualian adalah untuk menulis semua kode intervensi sedemikian rupa sehingga pengecualian sewenang-wenang dapat menyebar dari situs melemparnya ke handlernya, tiba dengan selamat dan tanpa merusak bagian lain dari program di sepanjang jalan.

Karena bahkan newmelempar pengecualian, setiap fungsi harus memberikan keamanan pengecualian dasar - kecuali jika hanya memanggil fungsi yang menjamin melempar pengecualian - kecuali Anda menonaktifkan pengecualian sama sekali di seluruh proyek Anda .

Karenanya, pengecualian adalah fitur "seluruh program" atau "seluruh tim", karena harus dipahami oleh semua orang di tim yang menggunakannya. Tapi tidak semua fitur C ++ seperti itu, sejauh yang saya tahu.

Contoh yang mungkin adalah bahwa jika saya tidak mendapatkan templat tetapi saya tidak menggunakannya, saya masih bisa menulis C ++ yang benar - atau tidak ?. Saya bahkan dapat memanggil sortarray bilangan bulat dan menikmati kecepatan keunggulannya yang luar biasa. C qsort(karena tidak ada fungsi pointer disebut), tanpa risiko bug - atau tidak? Tampaknya templat tidak "seluruh tim".

Apakah ada fitur C ++ lainnya yang kode dampak tidak langsung menggunakannya, dan karenanya "seluruh tim"? Saya terutama tertarik pada fitur yang tidak ada dalam C.

Pembaruan : Saya terutama mencari fitur di mana tidak ada tanda yang diberlakukan bahasa yang perlu Anda ketahui. Jawaban pertama yang saya sebutkan const benar, yang juga seluruh tim, maka semua orang perlu mempelajarinya; Namun, AFAICS hanya akan memengaruhi Anda jika Anda memanggil fungsi yang ditandai const, dan kompiler akan mencegah Anda memanggilnya pada objek non-const, sehingga Anda mendapatkan sesuatu untuk google. Dengan pengecualian, Anda bahkan tidak mendapatkannya; Selain itu, mereka selalu digunakan segera setelah Anda gunakan new, karenanya pengecualian lebih "berbahaya". Karena saya tidak dapat mengatakan ini secara objektif, saya akan menghargai fitur seluruh tim.

Pembaruan 2 : alih-alih fitur C ++ saya seharusnya menulis sesuatu seperti "C ++ - fitur spesifik", untuk mengecualikan hal-hal seperti multithreading yang berlaku untuk sejumlah besar bahasa pemrograman utama.

Lampiran: Mengapa pertanyaan ini objektif (jika Anda bertanya-tanya)

C ++ adalah bahasa yang kompleks, sehingga banyak proyek atau panduan pengkodean mencoba memilih fitur C ++ "sederhana", dan banyak orang mencoba untuk memasukkan atau mengecualikan beberapa yang menurut sebagian besar kriteria subyektif. Pertanyaan tentang hal itu harus ditutup secara teratur di sini di SO.

Di atas, sebagai gantinya, saya mendefinisikan (setepat mungkin) apa fitur bahasa "seluruh tim", memberikan contoh (pengecualian), bersama dengan bukti pendukung yang luas dalam literatur tentang C ++, dan meminta fitur seluruh tim dalam C ++ tanpa pengecualian.

Apakah Anda harus menggunakan fitur "seluruh tim", atau apakah itu konsep yang relevan, mungkin subjektif - tetapi itu hanya berarti pentingnya pertanyaan ini subjektif, seperti biasa.

Jawaban:


11

Saya akan mencalonkan konkurensi sebagai fitur 'seluruh tim'.

Meskipun dimungkinkan untuk mendesain perangkat lunak sedemikian rupa sehingga hanya beberapa ahli yang perlu mengetahui masalah konkurensi dan anggota tim lainnya dapat memperoleh manfaat tanpa memedulikan kompleksitas (seperti yang dapat Anda lakukan dengan templat), dalam praktiknya hal itu tidak bekerja seperti itu. Dalam praktiknya, jika Anda memiliki beberapa utas, maka Anda harus menganalisis dengan cermat untuk setiap variabel yang Anda gunakan jika ada masalah konkurensi potensial dengan penggunaan itu.


Saya setuju bahwa utas merupakan fitur seluruh tim, meskipun itu bukan C ++ - spesifik. Namun, ada juga antarmuka lain untuk konkurensi (bukan berbasis thread), sebagian besar dalam bahasa lain, dan beberapa yang memungkinkan konkurensi menjadi jauh lebih baik dienkapsulasi (meskipun ini masih merupakan topik penelitian saat ini dalam bahasa pemrograman). Jadi ini pertanyaan terbuka apakah ini berlaku untuk concurrency per-se.
Blaisorblade

@ Blaisorblade - C ++ 11 memperkenalkan pustaka threading sendiri, jadi ya, itu bagian dari C ++ sekarang.
Michael Kohne

@MichaelKohne: Saya tidak mengklaim bahwa C ++ tidak mendukung multithreading. Saya mengatakan bahwa utas bukan khusus C ++, karena banyak bahasa lain memilikinya. Saya baru saja mencatat bahwa masalah yang dijelaskan berlaku untuk utas sebagai antarmuka ke konkurensi.
Blaisorblade

Saya akan mengatakan "kondisi ras" adalah kata yang lebih baik untuk masalah inti ini. Artinya, programmer mungkin tidak perlu mengerjakan atau menggunakan kerangka kerja konkurensi sama sekali, tetapi jika mereka menulis kode C ++, dan kode mereka dapat berpotensi dipanggil dari lebih dari satu utas, maka mereka perlu memikirkan kondisi lomba secara umum, dalam semua kode mereka ditulis.
rwong

Itu mengingatkan saya pada miskomunikasi dengan rekan kerja yang terjadi bertahun-tahun yang lalu. Seorang rekan kerja bertanya kepada rekan kerja yang lain: apakah ini (beberapa fungsi) aman? Rekan kerja lainnya menjawab ya. Rekan kerja yang bertanya kemudian melanjutkan untuk menggunakannya dari beberapa utas, dan mendapatkan hasil yang tidak terduga (tidak macet, tetapi beberapa operasi diterapkan pada objek yang sama). Ternyata rekan kerja yang bertanya tidak memiliki model mental apa yang dimaksud dengan "benang-aman", dan mengira jawabannya sebagai "Saya bisa melakukan apa pun yang saya inginkan."
rwong

10

Jawaban yang jelas adalah constbenar: karena const/ volatilekualifikasi menular, begitu satu bagian dari kode mulai menggunakannya, setiap kode panggilan (langsung atau tidak langsung) juga harus constbenar, atau membuang constsecara eksplisit.

Namun, seperti halnya perkecualian, ini jelas merupakan hal yang baik . Lebih dari itu, karena tidak seperti keselamatan pengecualian itu diverifikasi ketat oleh kompiler.


2
Selain itu, const-correctness transparan: ini hanya tentang jenis yang Anda berikan ke fungsi (yang selalu terlihat) dan kompiler akan meneriaki Anda jika Anda salah. Saya sedang memikirkan hal-hal yang lebih buram, di mana Anda tidak tahu ada sesuatu yang salah sampai terlambat (dan bahkan kemudian, akan sulit untuk mengetahuinya). Tetapi jawaban Anda tetap menarik, karenanya terpilih.
Blaisorblade

10

Pointer.

  • Apakah pointer menunjuk ke memori pada stack?
  • Apakah pointer menunjuk ke memori pada heap?
  • Apakah pointer menunjuk ke satu objek?
  • Apakah pointer menunjuk ke array?
  • Apakah pointer menunjuk ke lokasi di tengah array?
  • Apakah pointer valid?
  • Apakah pointer rusak?
  • Kode apa yang "memiliki" pointer?
  • Haruskah objek yang direferensikan secara manual dialokasikan? Kalau begitu bagaimana?

1
+1 secara khusus karena pertanyaan tentang kepemilikan pointer. Tanpa petunjuk pintar, kepemilikan benar-benar menyebar di seluruh tim.
JKor

3

Kemungkinan lain adalah kelebihan operator. Setelah salah satu bagian dari basis kode mulai bermain-main dengan operator kelebihan beban orang cenderung mulai menebak-nebak apa sebenarnya setiap diberikan objek yang mereka bekerja dengan yang benar-benar melakukan. Itu tidak secara eksplisit menyebar melalui basis kode cara pengecualian dan kebenaran const lakukan, tapi itu pasti sesuatu yang dapat mulai menyebabkan masalah jika seluruh tim tidak pada halaman yang sama tentang kapan, bagaimana, dan mengapa menggunakannya.


1

Satu-satunya selain kebenaran konst (lihat di atas) yang muncul di benak adalah keadaan aliran. Jika Anda menulis kode C ++ di mana Anda menggunakan objek dan subobyek dan kemungkinan hierarki objek, Anda akhirnya ingin mengirim atau menerima data ke / dari operator program. Anda dapat menulis operasi streaming yang sederhana yang akan mengkompilasi dan akan menjadi semantik benar ...

std::ostream& operator<< (std::ostream&, MyClass const&) {...}
std::istream& operator>> (std::istream&, MyClass&) {...}

... Tetapi begitu Anda melakukannya, Anda tidak akan pernah memiliki jaminan bahwa apa yang Anda coba tulis (atau yang paling penting, baca) mengikuti format yang sama dengan apa yang dikirim oleh klien kepada Anda. Ada terlalu banyak kasus keanehan yang terjadi dengan stream, bahkan lebih buruk jika Anda harus melewati stream atau bendera stream sebagai argumen di rantai panggilan fungsi Anda ... yang biasanya diimplementasikan sebagai streaming kelas. Jadi streaming dapat didefinisikan sebagai "berbahaya" karena Anda menggunakan istilah di atas, atau mungkin bahkan sebagai "viral" ( meskipun tidak di mana pun pada tingkat yang sama dengan const-correctness ).

Punya anggota jauh di bawah hierarki kelas Anda yaitu a string? Kejutan, klien lebih baik mengirim satu kata, atau yang lain. Punya nomor yang ingin Anda buat bersambung? Anda lebih baik memeriksa, menyimpan, dan mengembalikan bendera streaming di setiap kedalaman panggilan fungsi, karena Anda tidak pernah tahu siapa idiot yang baru saja mengatur alirannya ke keluaran oktal sebelum memanggil fungsi Anda. Atau lebih buruk - yang baru saja memanggil sesuatu seperti setfilldan setwdengan demikian memecah format input / output pertama Anda - dan hanya anggota integral pertama Anda karena negara-negara tersebut tidak menyebar . Oh, dan jangan bertanya tentang stream dan internasionalisasi.

Tidak ada peringatan dalam bahasa apa pun yang Anda streaming dengan cara yang benar, atau cara yang salah, atau bahkan streaming sama sekali . Meminta kode klien untuk aliran agar dapat menulis data cadangan? Anda tidak benar-benar memiliki cara untuk mengetahui bahwa aliran menunjuk ke /dev/null. ( Di sisi lain, Anda dapat mengklaim kecepatan cadangan yang luar biasa dan tingkat kompresi seperti itu! )

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.