Rzeczywista odpowiedź to:
- Kompilator daje pierwszeństwo wartości „i == 0”, która daje wartość true.
- Następnie oceni i = 1 jako PRAWDA lub FAŁSZ, a ponieważ skompilowane operatory przypisania nigdy nie zawiodą (inaczej nie skompilowaliby), to również ocenia na prawdę.
- Ponieważ obie instrukcje są oceniane jako prawdziwe, a PRAWDA i PRAWDA jest PRAWDA, instrukcja if ma wartość PRAWDA.
Jako dowód spójrz na dane wyjściowe asm twojego kompilatora dla wprowadzonego kodu (wszystkie komentarze są moje):
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
Powyższy wynik asm pochodzi z CLANG, ale wszystkie inne kompilatory, na które patrzyłem, dawały podobne wyniki. Dotyczy to wszystkich kompilatorów w tej witrynie, bez względu na to, czy są to kompilatory czystego C, czy C ++, a wszystko to bez pragnienia zmiany trybu kompilatora (domyślnie C ++ dla kompilatorów C ++).
Zauważ, że twój kompilator tak naprawdę nie ustawił i = 1, ale i = TRUE (co oznacza dowolną 32-bitową niezerową wartość całkowitą). Jest tak, ponieważ operator && ocenia tylko, czy instrukcja ma wartość PRAWDA, czy FAŁSZ, a następnie ustawia wyniki zgodnie z tym wynikiem. Jako dowód spróbuj zmienić i = 1 na i = 2 i sam możesz zaobserwować, że nic się nie zmieni. Przekonaj się, korzystając z dowolnego kompilatora online w Eksploratorze kompilatorów
i
jest ustawiona na1
.