Mengapa tipe boolean dalam C ++ mendukung ++ tetapi tidak -?

29

Mengapa operator --tidak ada untuk bool sedangkan untuk operator++ ?

Saya mencoba di C ++, dan saya tidak tahu apakah pertanyaan saya berlaku untuk bahasa lain. Saya akan senang mengetahui juga.

Saya tahu , saya bisa menggunakan operator ++dengan bool. Itu membuat bool sama dengan true.

bool b = false;
b++;
// Now b == true.

Mengapa kita tidak bisa menggunakan operator --dengan cara yang berlawanan?

bool b = true;
b--;
// Now b == false;

Ini tidak terlalu berguna, tetapi saya ingin tahu.

aloisdg kata Reinstate Monica
sumber
8
Pertanyaan tentang StackOverflow ini mungkin mencerahkan.
Blrfl
Jadi alasan sejarah. Terima kasih atas tautannya. Bisakah Anda menulis jawaban dan saya meletakkannya sebagai terselesaikan?
aloisdg mengatakan Reinstate Monica
Tautan saja tidak membuat jawaban yang baik, dan tidak ada mekanisme yang baik untuk menandai pertanyaan ini sebagai duplikat dari sesuatu di situs SE lain.
Blrfl
1
Jadi kita harus membuka topik di meta.stackexchange.com atau sesuatu. Saya pikir Anda harus mendapatkan beberapa karma untuk tautan yang bagus dan jika seseorang menjengkelkan Anda, penulis dari jawaban aslinya harus mendapatkan beberapa karma. Bahkan, pertanyaan aslinya juga harus mendapatkan karma.
aloisdg berkata Reinstate Monica
2
@aloisdg dups lintas situs adalah masalah lama pada MSO. Mengejar pertanyaan terkait untuk mendapatkan pandangan yang lebih lengkap.

Jawaban:

53

Di masa lalu dari C, tidak ada tipe boolean. Orang-orang menggunakan intuntuk menyimpan data boolean, dan sebagian besar berhasil. Nol itu salah dan yang lainnya benar.

Ini berarti jika Anda mengambil int flag = 0;dan kemudian apakah flag++nilainya akan benar. Ini akan berfungsi tidak peduli berapa nilai bendera itu (kecuali jika Anda sering melakukannya, itu berguling dan Anda kembali ke nol, tetapi mari abaikan itu) - menambah bendera ketika nilainya 1 akan memberikan 2, yang masih benar.

Beberapa orang menggunakan ini untuk menetapkan tanpa syarat nilai boolean menjadi true. Saya tidak yakin itu menjadi idiomatik , tetapi dalam beberapa kode.

Ini tidak pernah berhasil --, karena jika nilainya lebih dari 1 (yang bisa jadi), nilainya tetap tidak salah. Dan jika itu sudah salah (0 ) dan Anda melakukan operator penurunan di atasnya, itu tidak akan tetap salah.

Ketika memindahkan kode dari C ke C ++ di masa-masa awal, sangat penting bahwa kode C yang termasuk dalam C ++ masih bisa berfungsi. Dan dalam spesifikasi untuk C ++ (bagian 5.2.6 (pada halaman 71)) berbunyi:

Nilai yang diperoleh dengan menerapkan postfix ++ adalah nilai yang dimiliki operan sebelum menerapkan operator. [Catatan: nilai yang diperoleh adalah salinan dari nilai aslinya] Operand harus merupakan nilai yang dapat dimodifikasi. Jenis operan harus merupakan tipe aritmatika atau penunjuk ke tipe objek lengkap. Setelah hasilnya dicatat, nilai objek diubah dengan menambahkan 1 padanya, kecuali objek tersebut bertipebool , dalam hal ini ia disetel ke true. [Catatan: penggunaan ini sudah usang, lihat lampiran D.]

Operan postfix - dikurangi secara analog ke operator postfix ++, kecuali operan tidak bertipe bool.

Ini lagi disebutkan dalam bagian 5.3.2 (untuk operator awalan - 5.2.6 pada postfix)

Seperti yang Anda lihat, ini sudah usang (Lampiran D dalam dokumen, halaman 709) dan tidak boleh digunakan.

Tapi itu sebabnya. Dan kadang-kadang Anda dapat melihat kode. Tapi jangan lakukan itu.

Komunitas
sumber
5
"Beberapa orang menggunakan ini untuk tanpa syarat menetapkan nilai boolean menjadi true." Sebut saja mereka orang bodoh, bukan orang.
Deduplicator
@Dupuplikator: Mungkin itu masalah kinerja: memuat nilai ke dalam variabel mungkin telah mengambil lebih banyak siklus prosesor daripada menambah variabel. Tentu saja, ini mungkin tidak masalah pada komputer modern.
Giorgio
1
@Iorgio itu sangat mungkin. Ingat bahwa C ditulis untuk mencocokkan dengan set instruksi PDP-7 dan PDP-11 memiliki tweak lainnya. Dari sini - "Orang-orang sering menebak bahwa mereka diciptakan untuk menggunakan mode penambahan-otomatis dan pengurangan-otomatis yang disediakan oleh DEC PDP-11 tempat C dan Unix pertama kali menjadi populer. Ini secara historis tidak mungkin, karena tidak ada PDP- 11 ketika B dikembangkan. PDP-7, bagaimanapun, memang memiliki beberapa sel memori `auto-increment ', dengan properti yang referensi memori tidak langsung melalui mereka menambah sel."
@Dupuplikator: Dalam kode yang menggunakan bilangan bulat untuk boolean, variabel yang bertambah untuk setiap ... apa pun ... dapat bertindak baik sebagai penghitung (berapa kali itu ditambahkan) dan sebagai boolean (apakah telah ditambahkan sama sekali atau tidak).
Keith Thompson
2

Untuk mengatasi sebagian kode legacy yang digunakan intatau mirip dengan tipe booleannya.

Mike Graham
sumber
1
Pertanyaan saya adalah duplikat dari sini stackoverflow.com/questions/3450420/… . Omong-omong, terima kasih atas jawaban Anda.
aloisdg mengatakan Reinstate Monica
1

Untuk memahami signifikansi historis dari pertanyaan ini, Anda harus mempertimbangkan kasus Therac-25. Therac-25 adalah perangkat medis yang mengirimkan radiasi kepada pasien kanker. Itu terganggu dengan praktik pemrograman yang buruk yang berkontribusi terhadap rekam jejak keselamatan yang buruk (dengan beberapa kematian dikaitkan dengannya).

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(buka bagian bawah halaman 3)

Setiap melewati Uji Set-Up rutin meningkatkan pemeriksaan posisi kolimator atas, variabel bersama yang disebut Class3. Jika Class3 bukan nol, ada inkonsistensi dan pengobatan tidak boleh dilanjutkan. Nilai nol untuk Class3 menunjukkan bahwa parameter yang relevan konsisten dengan perawatan, dan balok tidak terhambat.

...

Selama pengaturan mesin, Tes Pengaturan akan dijalankan beberapa ratus kali karena menjadwal ulang dirinya sendiri menunggu acara lain terjadi. Dalam kode tersebut, variabel Class3 bertambah satu per setiap lulus melalui Tes Pengaturan. Karena variabel Class3 adalah 1 byte, itu hanya dapat berisi nilai maksimum 255 desimal. Dengan demikian, pada setiap 256 kali melewati kode Set-Up Test, variabel meluap dan memiliki nilai nol. Itu berarti bahwa pada setiap 256 kali melewati Tes Pengaturan, kolimator atas tidak akan diperiksa dan kesalahan kolimator atas tidak akan terdeteksi. Eksposur berlebih terjadi ketika operator menekan tombol "set" pada saat yang tepat ketika Class3 bergeser ke nol. Dengan demikian Chkcol tidak dieksekusi, dan F $ mal tidak diatur untuk menunjukkan kolimator atas masih dalam posisi field-light. Perangkat lunak menyalakan 25 MeV penuh tanpa target di tempat dan tanpa pemindaian. Sinar elektron yang sangat terkonsentrasi dihasilkan, yang tersebar dan dibelokkan oleh cermin stainless steel yang ada di jalur.

Therac-25 menggunakan sesuatu yang mirip dengan operator++pada a bool. Namun, bahasa pemrograman yang mereka gunakan bukan C ++, dan tipe datanya tidak bool. Berbeda dengan jaminan di C ++, tipe integer biasa terus naik. Tipe data mereka setara denganuint8_t .

C ++ memutuskan untuk mempertahankan operator++sekitar bagi orang-orang yang terbiasa dengan pemrograman seperti ini, tetapi alih-alih menambah nilainya, ia hanya menetapkannya menjaditrue untuk mencegah hal-hal seperti ini.

Perhatikan bahwa operator++(bool)sudah usang.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

Lampiran D dari C ++ 14:

D.1 Operator increment dengan operan bool
Penggunaan operan bertipe bool dengan operator ++ sudah usang (lihat 5.3.2 dan 5.2.6).

David Stone
sumber
Sementara itu akan menjelaskan mengapa itu usang, itu tidak menjelaskan mengapa itu ada di tempat pertama.
Itu ada karena ada beberapa orang yang menetapkan nilai boolean dengan menambahkannya ketika pemrograman dalam C. C ++ dirancang untuk memudahkan transisi dari C, jadi mereka mendukungnya dengan booltipe. Saya hanya mencoba memberikan contoh sejarah ketika orang benar-benar memprogram dengan cara ini.
David Stone