Rodzaj warunkowy stosowany w pętli może ograniczać rodzaje optymalizacji, które kompilator może wykonać, na lepsze lub na gorsze. Na przykład biorąc pod uwagę:
uint16_t n = ...;
for (uint16_t i=1; i<=n; i++)
... [loop doesn't modify i]
kompilator mógłby założyć, że powyższy warunek powinien spowodować zakończenie pętli po pętli n -tego przejścia, chyba że n może 65535, a pętla może wyjść w inny sposób niż przez przekroczenie n. Jeśli te warunki mają zastosowanie, kompilator musi wygenerować kod, który spowodowałby uruchomienie pętli, dopóki coś innego niż powyższy warunek nie spowoduje jej wyjścia.
Jeśli zamiast tego pętla została zapisana jako:
uint16_t n = ...;
for (uint16_t ctr=0; ctr<n; ctr++)
{
uint16_t i = ctr+1;
... [loop doesn't modify ctr]
}
wtedy kompilator mógłby bezpiecznie założyć, że pętla nigdy nie będzie musiała wykonywać więcej niż n razy, a zatem może być w stanie wygenerować bardziej wydajny kod.
Pamiętaj, że każde przepełnienie podpisanymi typami może mieć paskudne konsekwencje. Dany:
int total=0;
int start,lim,mult; // Initialize values somehow...
for (int i=start; i<=lim; i++)
total+=i*mult;
Kompilator może przepisać to jako:
int total=0;
int start,lim,mult; // Initialize values somehow...
int loop_top = lim*mult;
for (int i=start; i<=loop_top; i+=mult)
total+=i;
Taka pętla zachowywałaby się identycznie jak oryginał, gdyby w obliczeniach nie wystąpiło przepełnienie, ale mogłaby działać wiecznie, nawet na platformach sprzętowych, gdzie przepełnienie liczb całkowitych normalnie miałoby spójną semantykę zawijania.