Il tipo di condizionale utilizzato in un ciclo può limitare i tipi di ottimizzazioni che un compilatore può eseguire, nel bene e nel male. Ad esempio, dato:
uint16_t n = ...;
for (uint16_t i=1; i<=n; i++)
... [loop doesn't modify i]
un compilatore potrebbe presumere che la condizione di cui sopra dovrebbe causare l'uscita del loop dopo l'ennesimo loop di passaggio a meno che n non possa 65535 e il loop potrebbe uscire in qualche modo diverso da quelli che superano n. Se si applicano tali condizioni, il compilatore deve generare un codice che provocherebbe l'esecuzione del ciclo fino a quando qualcosa di diverso dalla condizione precedente lo fa uscire.
Se il ciclo fosse invece stato scritto come:
uint16_t n = ...;
for (uint16_t ctr=0; ctr<n; ctr++)
{
uint16_t i = ctr+1;
... [loop doesn't modify ctr]
}
quindi un compilatore potrebbe tranquillamente supporre che il ciclo non debba mai essere eseguito più di n volte e potrebbe quindi essere in grado di generare codice più efficiente.
Si noti che qualsiasi overflow con tipi firmati può avere conseguenze spiacevoli. Dato:
int total=0;
int start,lim,mult; // Initialize values somehow...
for (int i=start; i<=lim; i++)
total+=i*mult;
Un compilatore potrebbe riscriverlo come:
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;
Un ciclo di questo tipo si comporterebbe in modo identico all'originale se non si verifica alcun overflow nei calcoli, ma potrebbe funzionare per sempre anche su piattaforme hardware in cui l'overflow di numeri interi avrebbe normalmente una semantica di wrapping coerente.