Per uno, non è il tipo di "cicli di CPU sprecati" di cui devi preoccuparti. Anche se la seconda condizione è stata verificata, è un ciclo o due. I principianti si preoccupano dei nanosecondi. I programmatori esperti si preoccupano dei microsecondi (ero solito dire che si preoccupano dei millisecondi, ma i tempi stanno cambiando). Si chiama micro-ottimizzazioni ed è il tipo di cosa che produce codice illeggibile senza dare alcun vantaggio di velocità, e in seguito impedisce l'ottimizzazione reale perché il codice è troppo difficile da mantenere.
Dalla definizione del linguaggio, in C, C ++, Objective-C, Java, C # e probabilmente in molti altri linguaggi, è ben definito che una logica o valuta il lato sinistro prima. Se il lato sinistro è diverso da zero, allora il lato destro è non valutato affatto. Se il lato sinistro è zero, solo allora viene toccato il lato destro.
(I compilatori sono liberi di fare ciò che preferiscono purché non cambi il comportamento ufficiale che faranno se è più veloce).
E nel tuo caso particolare, dopo un assegnamento i = 2 il compilatore non produrrà codice per fare alcun confronto, perché conosce già il risultato. i == 2 è vero, quindi i == 4 non è affatto valutato.