konversi bool to int

131

Seberapa portabel konversi ini. Bisakah saya yakin bahwa kedua pernyataan itu lulus?

int x = 4<5;
assert(x==1);

x = 4>5;
assert(x==0);

Jangan tanya kenapa. Saya tahu itu jelek. Terima kasih.

pic11
sumber
Mengapa Anda tidak mengubah ekspresi pertama? Kamu bisa menulis assert(x!=0). Bahkan jika bool (true) mengkonversi portable ke int (1), pernyataan "not false" memiliki ekspresi yang lebih mudah dibaca.
pemain harpa
1
Mengapa tidak: assert( 4 < 5);danassert(!( 4 > 5));
Martin York
4
@harper: Menggunakan nilai ekspresi perbandingan yang diperlukan sangat masuk akal.
R .. GitHub BERHENTI MEMBANTU ICE
@ R._ Ketika pertanyaannya adalah apakah konversi bool-to-int memberikan hasil yang masuk akal, saya tidak akan bergantung pada ini. Ketika penulis memiliki keraguan bahwa persyaratan ini terpenuhi, pembaca bisa mendapatkan masalah yang sama. Terutama karena nilai x bukanlah kondisi untuk memeriksa tetapi hanya hasil antara.
pemain harpa
3
Saya mungkin akan menulis (4 < 5) ? 1 : 0jika saya benar-benar perlu mengubah boolean menjadi 0 atau 1. Kompiler yang baik kemungkinan akan menghasilkan kode mesin yang sama dan lebih jelas untuk pembaca manusia.
ollb

Jawaban:

205
int x = 4<5;

Benar-benar portabel. Konforman standar. booluntuk intkonversi implisit!

§4.7 / 4 dari C ++ Standard mengatakan ( Konversi Integral )

Jika jenis sumbernya bool, nilainya falsedikonversi ke nol dan nilainya truedikonversi menjadi satu .


Adapun C, sejauh yang saya tahu tidak ada booldi C. (sebelum 1999) Jadi booluntuk intkonversi relevan dalam C ++ saja. Dalam C, 4<5mengevaluasi ke intnilai, dalam hal ini nilainya 1, 4>5 akan dievaluasi menjadi 0.

EDIT: Jens dalam komentar tersebut mengatakan, C99 memiliki _Booltipe. booladalah makro yang didefinisikan dalam stdbool.hfile header. truedan falsejuga makro didefinisikan dalam stdbool.h.

§7,16 dari C99 mengatakan,

Makro booldiperluas ke _Bool.

[..] trueyang mengembang ke konstanta integer 1, false yang mengembang ke konstanta integer 0, [..]

Nawaz
sumber
3
yakin bahwa ada booldi C sejak 1999. Cukup gunakan header "stdbool.h" dan ini harus dimasukkan.
Jens Gustedt
1
Memang, saya memeriksanya di beberapa kompiler dan tampaknya portabel.
pic11
8
Terlepas dari versi bahasa C dan ketersediaan bool/ _Booljenis, operator relasional dalam C menghasilkan int, bukan bool. Yaitu bahkan di C99, operator relasional masih menghasilkan int.
AnT
51

Anda menandai pertanyaan Anda [C] dan [C ++] secara bersamaan. Hasilnya akan konsisten di antara bahasa-bahasa tersebut, tetapi struktur jawabannya berbeda untuk masing-masing bahasa ini.

Dalam bahasa C, contoh Anda tidak memiliki kaitan dengan boolapa pun (yang juga berlaku untuk C99). Dalam bahasa C operator relasional tidak membuahkan boolhasil. Keduanya 4 > 5dan 4 < 5merupakan ekspresi yang menghasilkan hasil tipe intdengan nilai 0atau 1. Jadi, tidak ada "konversi bool ke int" dalam bentuk apa pun yang terjadi dalam contoh Anda di C.

Dalam C ++ operator relasional memang menghasilkan boolhasil. boolnilai-nilai dapat dikonversi untuk intmengetik, dengan truemengkonversi ke 1dan falsemengkonversi ke 0. Ini dijamin oleh bahasa.

Bahasa PS C juga memiliki tipe boolean khusus _Bool(alias makro bool), dan aturan konversi integralnya pada dasarnya sama dengan di C ++. Namun demikian ini tidak relevan dengan contoh spesifik Anda dalam C. Sekali lagi, operator relasional di C selalu menghasilkan int(tidak bool) hasil terlepas dari versi spesifikasi bahasa.

Semut
sumber
2
Itu benar, tidak ada bool dalam K&R C. Saya menandai ulang pertanyaan saya sebagai C99.
pic11
@ pic11: Tidak perlu melakukan retag apa pun. Ini tidak ada hubungannya dengan K&R atau C. lainnya. Meskipun ada booldi C99, operator relasional masih memproduksi intdi C99, tidak bool. Jadi, jika itu adalah operator relasional khusus yang Anda minati (seperti dalam contoh Anda), masalahnya masih belum ada hubungannya bool.
AnT
Sekarang saya mengerti. Hasil dari operator hubungan secara implisit dapat dikonversi ke int. Ini benar dalam C, C99 dan C ++. Diisi ulang lagi.
pic11
3
@ pic11: Tidak, kamu tidak mengerti. Dalam C, termasuk C99, hasil dari operator pembanding adalah int, bukan a bool. Tidak ada konversi yang terjadi.
R .. GitHub BERHENTI MEMBANTU ICE
Apakah ada cara yang sesuai standar melalui mana bahasa dapat memiliki tipe yang berperilaku seperti booltetapi tidak memungkinkan alamatnya diambil? Banyak sistem embedded menggunakan tipe seperti itu (sering dinyatakan menggunakan pengenal bit). Pada misalnya PIC mid-range, if (bitVar1) bitVar2=1;akan ada dua instruksi; pengkodean optimal untuk if (byteVar1) byteVar2=1;setidaknya empat (pada banyak kompiler, mungkin lima). Jenis seperti itu dapat menawarkan peningkatan kinerja yang besar.
supercat
17

Bagian 6.5.8.6 dari standar C mengatakan:

Masing-masing operator <(kurang dari),> (lebih besar dari), <= (kurang dari atau sama dengan), dan> = (lebih besar dari atau sama dengan) akan menghasilkan 1 jika hubungan yang ditentukan benar dan 0 jika itu adalah false.) Hasilnya bertipe int.


sumber
Terima kasih untuk referensi. Tampaknya benar == 1 karena alasan historis.
pic11
2

Tampaknya tidak ada masalah karena int ke bool cast dilakukan secara implisit. Ini berfungsi di kompiler Microsoft Visual C ++, GCC dan Intel C ++. Tidak ada masalah di C atau C ++.

Alex James
sumber
2
"Ini berfungsi dalam beberapa kasus" bukan cara yang baik untuk memeriksa kebenaran, terutama dengan versi alat yang tidak ditentukan. Saya lebih suka pendekatan dalam jawaban lain; mereka tidak dapat menjamin implementasi tertentu benar, tetapi mereka dapat menjamin apa yang akan dilakukan implementasi yang benar.
Matius Baca