La respuesta real es:
- El compilador da prioridad a "i == 0", que se evalúa como verdadero.
- Luego evaluará i = 1 como VERDADERO o FALSO, y dado que los operadores de asignación compilados nunca fallan (de lo contrario no compilarían), también se evalúa como verdadero.
- Dado que ambas declaraciones se evalúan como verdaderas, y VERDADERO && VERDADERO se evalúa como VERDADERO, la declaración if se evaluará como VERDADERO.
Como prueba, solo mira la salida asm de tu compilador para el código que ingresaste (todos los comentarios son míos):
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
La salida asm anterior era de CLANG, pero todos los otros compiladores que miré dieron una salida similar. Esto es cierto para todos los compiladores en ese sitio, ya sean compiladores C o C ++ puros, todo sin ningún pragma para cambiar el modo del compilador (que por defecto es C ++ para los compiladores C ++)
Tenga en cuenta que su compilador en realidad no estableció i = 1, pero i = TRUE (lo que significa cualquier valor entero no cero de 32 bits). Esto se debe a que el operador && solo evalúa si una declaración es VERDADERA o FALSA, y luego establece los resultados de acuerdo con ese resultado. Como prueba, intente cambiar i = 1 a i = 2 y podrá observar por sí mismo que nada cambiará. Compruébelo usted mismo utilizando cualquier compilador en línea en Compiler Explorer
i
se establece en1
.