คำตอบที่แท้จริงคือ:
- คอมไพเลอร์ให้ความสำคัญกับ "i == 0" ซึ่งประเมินว่าเป็นจริง
- จากนั้นมันจะประเมินค่า i = 1 เป็น TRUE หรือ FALSE และเนื่องจากตัวดำเนินการที่ได้รับมอบหมายที่รวบรวมไว้จะไม่ล้มเหลว
- เนื่องจากทั้งสองข้อความประเมินว่าเป็นจริงและ TRUE && TRUE ประเมินเป็น TRUE ข้อความสั่ง if จะประเมินเป็น TRUE
เพื่อเป็นการพิสูจน์ให้ดูที่เอาต์พุต asm ของคอมไพเลอร์ของคุณสำหรับโค้ดที่คุณป้อน (ความคิดเห็นทั้งหมดเป็นของฉันเอง):
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
เอาต์พุต asm ด้านบนมาจาก CLANG แต่คอมไพเลอร์อื่น ๆ ทั้งหมดที่ฉันดูให้เอาต์พุตเหมือนกัน สิ่งนี้เป็นจริงสำหรับคอมไพเลอร์ทั้งหมดในไซต์นั้นไม่ว่าจะเป็นคอมไพเลอร์ C หรือ C ++ ล้วน แต่ไม่มี pragmas ใด ๆ เพื่อเปลี่ยนโหมดของคอมไพเลอร์ (โดยค่าเริ่มต้นคือ C ++ สำหรับคอมไพเลอร์ C ++)
โปรดทราบว่าคอมไพเลอร์ของคุณไม่ได้ตั้งค่า i = 1 แต่ i = TRUE (ซึ่งหมายถึงค่าจำนวนเต็ม 32- บิตไม่เป็นศูนย์) นั่นเป็นเพราะผู้ประกอบการ && ประเมินเฉพาะว่าข้อความเป็น TRUE หรือ FALSE จากนั้นตั้งค่าผลลัพธ์ตามผลลัพธ์ เพื่อพิสูจน์ลองเปลี่ยน i = 1 เป็น i = 2 และคุณสามารถสังเกตด้วยตัวคุณเองว่าไม่มีอะไรเปลี่ยนแปลง ดูตัวเองด้วยการใช้คอมไพเลอร์ออนไลน์ที่Compiler Explorer
i
1