Dapatkah saya berasumsi (bool) true == (int) 1 untuk kompiler C ++?

118

Dapatkah saya berasumsi (bool)true == (int)1untuk kompiler C ++?

Petruza
sumber
3
Pemeran dalam pertanyaan Anda berlebihan, haruskah dibalik?
GManNickG
9
Dia tidak bermaksud mereka menjadi pemain, maksudnyabool t = true; int n = 1; if (t == n) {...} ;
egrunin
7
@egrunin: Eh, tapi benar itu bool dan 1 int juga. :)
GManNickG
1
Benar, saya bermaksud menyatakan jenis nilainya.
Petruza
2
(int) trueadalah 1sebagai nilai integer, tetapi sesuatu yang if (pointer)melewati bagian then if pointer != 0. Satu-satunya hal yang dapat Anda anggap benar adalah itu false == 0, dan true != 0(dan trueevaluasi 1ketika dilemparkan ke int)
Luis Colorado

Jawaban:

134

Iya. Pemerannya berlebihan. Dalam ekspresi Anda:

true == 1

Promosi integral berlaku dan nilai bool akan dipromosikan menjadi intdan promosi ini harus menghasilkan 1.

Referensi: 4.7 [konv.integral] / 4: Jika tipe sumber adalah bool... truediubah menjadi satu.

CB Bailey
sumber
9
@Joshua: trueadalah kata kunci yang ditentukan oleh bahasa. Itu tidak dapat didefinisikan ulang oleh perpustakaan. #defines tidak diperbolehkan untuk mendefinisikan ulang kata kunci.
jalf
21
@jalf: # define memang diizinkan untuk menentukan kata kunci sistem. Tahap pra-pemrosesan dari kompilasi C murni tekstual, dan tidak mengetahui kata kunci atau sintaks C secara umum. Namun demikian, mendefinisikan ulang kata kunci bahasa hampir selalu merupakan ide yang buruk.
Dale Hagglund
2
@jalan. Mereka tidak? Lihat gcc.gnu.org/onlinedocs/cpp/Macros.html , dan setidaknya salah satu entri dalam Kontes Kode C Internasional yang Disamarkan, yang pernah menanyakan "Kapan waktu tungguwhile ?" (Jawaban: ketika dibutuhkan dua parameter, karena entri #defineditu harus printf.)
Ken Bloom
3
C99, §6.10.1 / 1 mengatakan: "Ekspresi yang mengontrol penyertaan bersyarat harus berupa ekspresi konstanta integer kecuali bahwa: tidak boleh mengandung cast; pengenal (termasuk yang secara leksikal identik dengan kata kunci) diinterpretasikan seperti yang dijelaskan di bawah ini;" Meskipun tidak dinyatakan sebagai izin langsung, ini dengan jelas mempertimbangkan kemungkinan makro yang "identik secara leksikal" dengan kata kunci.
Jerry Coffin
2
Oh, dan #defines diizinkan untuk mendefinisikan ulang kata kunci. C ++ 1x menyebabkan terlalu banyak masalah dengan kata kunci barunya sehingga persyaratan tersebut harus dihapus.
Joshua
18

Jawaban Charles Bailey benar. Kata-kata yang tepat dari standar C ++ adalah (§4.7 / 4): "Jika jenis sumbernya bool, nilai false diubah menjadi nol dan nilai true diubah menjadi satu."

Sunting: Saya melihat dia menambahkan referensi juga - Saya akan segera menghapus ini, jika saya tidak terganggu dan lupa ...

Sunting2: Kemudian lagi, mungkin perlu dicatat bahwa sementara nilai Boolean itu sendiri selalu dikonversi ke nol atau satu, sejumlah fungsi (terutama dari pustaka standar C) mengembalikan nilai yang "pada dasarnya Boolean", tetapi direpresentasikan sebagai ints yang biasanya hanya perlu nol untuk menunjukkan salah atau bukan nol untuk menunjukkan benar. Misalnya, fungsi is * <ctype.h>hanya memerlukan nol atau bukan nol, tidak harus nol atau satu.

Jika Anda mentransmisikannya ke bool, nol akan dikonversi menjadi salah, dan bukan nol menjadi benar (seperti yang Anda harapkan).

Jerry Coffin
sumber
9

Menurut standar, Anda harus aman dengan asumsi itu. Jenis C ++ boolmemiliki dua nilai - truedan falsedengan nilai yang sesuai 1 dan 0.

Hal yang harus diperhatikan adalah mencampurkan boolekspresi dan variabel dengan BOOLekspresi dan variabel. Yang terakhir didefinisikan sebagai FALSE = 0dan TRUE != FALSE, yang cukup sering dalam praktiknya berarti bahwa nilai apa pun yang berbeda dari 0 dipertimbangkan TRUE.

Banyak kompiler modern sebenarnya akan mengeluarkan peringatan untuk kode apa pun yang secara implisit mencoba mentransmisikan BOOLke booljika BOOLnilainya berbeda dari 0 atau 1.

Franci Penov
sumber
3

Saya telah menemukan kompiler yang berbeda memberikan hasil yang berbeda pada true. Saya juga menemukan bahwa seseorang hampir selalu lebih baik membandingkan bool dengan bool daripada int. Int tersebut cenderung berubah nilai dari waktu ke waktu saat program Anda berkembang dan jika Anda mengasumsikan true sebagai 1, Anda dapat digigit oleh perubahan yang tidak terkait di tempat lain dalam kode Anda.

Michael Dorgan
sumber
3
Ini adalah jawaban yang salah untuk C ++, seperti truekata kunci bahasa dengan perilaku yang ditentukan. Jika Anda merujuk ke makro yang ditentukan secara umum seperti TRUE, itu benar.
David Thornley
1
Mungkin pengalaman saya adalah dengan kompiler C - Saya telah menghabiskan banyak waktu dengan mereka selama bertahun-tahun. Maksud saya tentang secara langsung menggunakan ekspresi mathetical dalam pernyataan if berdiri. Kami memiliki kode yang melihat jika sedikit pergeseran bukan nol dalam jika, maka orang lain mengambil nilai bukan nol yang sama dan mengasumsikan itu adalah 1 dan meledakkan barang. Konversi sederhana menjadi true / 1 akan mencegah hal itu.
Michael Dorgan
Saya juga telah melihat perilaku seperti ini. Harus diakui, terakhir kali saya melihatnya sekitar tahun 1999. Saya menggunakan GCC. Bahasanya C. Tetap saja, saya memang pernah melihat perilaku seperti itu.
thb