Jawaban sebenarnya adalah:
- Kompiler memberikan prioritas pada "i == 0", yang dievaluasi menjadi true.
- Kemudian akan mengevaluasi i = 1 sebagai TRUE atau FALSE, dan karena operator penugasan yang dikompilasi tidak pernah gagal (jika tidak mereka tidak akan mengkompilasi), ia juga mengevaluasi ke true.
- Karena kedua pernyataan dievaluasi sebagai benar, dan TRUE && TRUE mengevaluasi ke TRUE, pernyataan jika akan mengevaluasi ke TRUE.
Sebagai bukti, lihat saja asm output dari kompiler Anda untuk kode yang Anda masukkan (semua komentar adalah milik saya):
mov dword ptr [rbp - 8], 0 ; i = 0;
cmp dword ptr [rbp - 8], 0 ; i == 0?
sete al ; TRUE (=1)
mov cl, al
and cl, 1 ; = operator always TRUE
movzx edx, cl
mov dword ptr [rbp - 8], edx ; set i=TRUE;
test al, 1 ; al never changed,
; so final ans is TRUE
Output asm di atas berasal dari CLANG, tetapi semua kompiler lain yang saya lihat memberikan hasil yang serupa. Ini berlaku untuk semua kompiler di situs itu, apakah mereka adalah kompiler C murni atau C ++, semua tanpa pragma untuk mengubah mode kompiler (yang secara default adalah C ++ untuk kompiler C ++)
Perhatikan bahwa kompiler Anda tidak benar-benar mengatur i = 1, tetapi i = BENAR (yang berarti 32-bit bukan nilai integer nol). Itu karena operator && hanya mengevaluasi apakah pernyataan itu BENAR atau SALAH, dan kemudian menetapkan hasil sesuai dengan hasil itu. Sebagai bukti, coba ubah i = 1 ke i = 2 dan Anda dapat mengamati sendiri bahwa tidak ada yang akan berubah. Lihat sendiri menggunakan kompiler online di Compiler Explorer
i
diatur ke1
.