Фактична відповідь:
- Компілятор надає перевагу "i == 0", що оцінює істинно.
- Тоді він оцінить i = 1 як TRUE або FALSE, а оскільки компільовані оператори присвоєння ніколи не виходять з ладу (інакше вони не збираються), він також оцінює як true.
- Оскільки обидва твердження оцінюються як істинні, а 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 ++, і всі без будь-яких прагм змінити режим компілятора (який за замовчуванням є C ++ для компіляторів C ++)
Зауважте, що ваш компілятор насправді не встановив i = 1, але i = TRUE (це означає, що будь-яке 32-бітове не нульове ціле число). Це тому, що оператор && оцінює лише те, чи твердження є ІСТИЧНИМ чи ЛІЖНИМ, і потім встановлює результати відповідно до цього результату. Як доказ, спробуйте змінити i = 1 на i = 2, і ви можете самі помітити, що нічого не зміниться. Побачте, використовуючи будь-який онлайн-компілятор у Провідник Compiler
i
встановлено1
.