Apakah ada "hal yang sangat buruk" yang dapat terjadi &&=
dan ||=
digunakan sebagai gula sintaksis untuk bool foo = foo && bar
dan bool foo = foo || bar
?
c++
boolean-operations
Kache
sumber
sumber
x ||= y
kira - kira setara dengan C ++x = x ? x : y;
untuk semua tipe? Dengan kata lain, "setel ke y jika belum disetel". Itu jauh lebih berguna daripada C atau C ++x ||= y
, yang (pemblokiran operator yang berlebihan) akan melakukan "setel x ke(bool)y
kecuali sudah disetel". Saya tidak ingin menambahkan operator lain untuk itu, sepertinya agak lemah. Tulis sajaif (!x) x = (bool)y
. Tapi kemudian, saya tidak benar-benar menggunakanbool
variabel cukup untuk menginginkan operator tambahan yang hanya benar-benar berguna dengan satu jenis itu.&&=
atau||=
hanya karena C tidak memilikinya. Saya cukup yakin alasan C tidak memilikinya adalah karena fungsinya dianggap tidak cukup menguntungkan.bool foo = foo || bar;
akan memunculkan perilaku tidak terdefinisi karenafoo
tidak diinisialisasi sebelum evaluasifoo || bar
. Tentu saja, ini dimaksudkan sebagai sesuatu yang disukaibool foo = …initialization…; …; foo = foo || bar;
dan pertanyaannya kemudian menjadi valid.Jawaban:
A
bool
mungkin hanyatrue
ataufalse
dalam C ++. Dengan demikian, menggunakan&=
dan|=
relatif aman (meskipun saya tidak terlalu menyukai notasinya). Benar, mereka akan melakukan operasi bit daripada operasi logis (dan dengan demikian mereka tidak akan mengalami hubungan pendek) tetapi operasi bit ini mengikuti pemetaan yang ditentukan dengan baik, yang secara efektif setara dengan operasi logis, selama kedua operan adalah tipebool
. 1Bertentangan dengan apa yang orang lain katakan di sini,
bool
dalam C ++ tidak boleh memiliki nilai yang berbeda seperti2
. Saat menetapkan nilai itu ke abool
, itu akan diubah menjaditrue
sesuai standar.Satu-satunya cara untuk memasukkan nilai yang tidak valid menjadi a
bool
adalah dengan menggunakanreinterpret_cast
on pointer:Tetapi karena kode ini menghasilkan perilaku yang tidak terdefinisi, kami dapat dengan aman mengabaikan potensi masalah ini dalam menyesuaikan kode C ++.
1 Harus diakui, ini adalah peringatan yang cukup besar seperti yang digambarkan oleh komentar Angew:
Alasannya adalah yang
b & 2
melakukan promosi integer sedemikian rupa sehingga ekspresi tersebut kemudian setara denganstatic_cast<int>(b) & 2
, yang menghasilkan0
, yang kemudian diubah kembali menjadi abool
. Jadi memang benar keberadaan sebuahoperator &&=
akan meningkatkan keamanan tipe.sumber
||
dan&&
shortcut, yaitu argumen kedua bukan operan jika operan pertama adalahtrue
(resp.false
for&&
).|
,&
,|=
Dan&=
selalu mengevaluasi kedua operan.&=
untuk sisi kiri dari jenisbool
, karena itu sangat mungkin untuk sisi kanan menjadi tipe selainbool
(sepertiislower
atau fungsi stdlib C lain yang kembali nol untuk nilai sebenarnya). Jika kita memiliki hipotesis&&=
, itu mungkin akan memaksa sisi kanan untuk beralih kebool
, yang&=
tidak. Dengan kata lain,bool b = true; b &= 2;
menghasilkanb == false
.&&
dan&
memiliki semantik yang berbeda:&&
tidak akan mengevaluasi operan kedua jika operan pertama adalahfalse
. yaitu sesuatu sepertiaman, tapi
tidak, meskipun kedua operan memiliki tipe
bool
.Hal yang sama berlaku untuk
&=
dan|=
:akan berperilaku berbeda dari:
sumber
Jawaban singkat
Semua operator
+=
,-=
,*=
,/=
,&=
,|=
... adalah aritmatika dan memberikan harapan yang sama:Namun, operator
&&=
dan||=
akan logis, dan operator ini mungkin rawan kesalahan karena banyak pengembang akanfoo()
selalu dipanggilx &&= foo()
.Apakah kita benar-benar perlu membuat C / C ++ lebih kompleks untuk mendapatkan jalan pintas
x = x && foo()
?Apakah kita benar-benar ingin lebih mengaburkan pernyataan samar
x = x && foo()
?Atau apakah kita ingin menulis kode yang bermakna seperti
if (x) x = foo();
?Jawaban panjang
Contoh untuk
&&=
Jika
&&=
operator tersedia, maka kode ini:setara dengan:
Kode pertama ini rawan error karena banyak developer akan mengira
f2()
selalu dipanggil berapapun nilai yangf1()
dikembalikan. Ini seperti menulis dibool ok = f1() && f2();
manaf2()
dipanggil hanya ketikaf1()
kembalitrue
.f2()
dipanggil saatf1()
kembalitrue
, maka kode kedua di atas tidak terlalu rentan terhadap kesalahan.f2()
selalu dipanggil),&=
cukup:Contoh untuk
&=
Selain itu, lebih mudah bagi kompiler untuk mengoptimalkan kode di atas daripada kode di bawah ini:
Bandingkan
&&
dan&
Kita mungkin bertanya-tanya apakah operator
&&
dan&
memberikan hasil yang sama bila diterapkan padabool
nilai?Mari kita periksa menggunakan kode C ++ berikut:
Keluaran:
Kesimpulan
Oleh karena itu YA kita dapat mengganti
&&
dengan&
untukbool
nilai ;-)Jadi lebih baik gunakan
&=
daripada&&=
.Kami bisa mempertimbangkan
&&=
tidak berguna bagi boolean.Sama untuk
||=
Jika pengembang ingin
f2()
dipanggil hanya saatf1()
kembalifalse
, bukan:Saya menyarankan alternatif yang lebih mudah dipahami berikut ini:
atau jika Anda lebih suka gaya semua dalam satu baris :
sumber
success = success && DoImportantStuff()
if(success) success = DoImportantStuff()
. Jika pernyataansuccess &&= DoImportantStuff()
itu diizinkan, banyak pengembang akan menganggapDoImportantStuff()
selalu disebut apa pun nilainyasuccess
. Semoga ini menjawab pertanyaan Anda ... Saya juga telah meningkatkan banyak bagian dari jawaban saya. Tolong beri tahu saya jika jawaban saya lebih bisa dimengerti sekarang? (tentang tujuan komentar Anda) Cheers, See you ;-)success &&= DoImportantStuff()
itu dibiarkan, banyak developer akan mengiraDoImportantStuff()
selalu menyebut apa pun nilai kesuksesannya." Anda bisa mengatakan ituif (success && DoImportantStuff())
. Selama mereka mengingat logika di balik sintaks if, mereka seharusnya tidak mengalami masalah&&=
.f1()
selalu mengevaluasi dalamok &&= f(1)
tetapi tidak akan menganggap itu selalu mengevaluasi dalamok = ok && f(1)
. Sepertinya bagi saya.v1 += e2
menjadi gula sintaksis yang setarav1 = v1 + e1
untuk variabel v1 dan ekspresi e2. Hanya notasi steno, itu saja.