ループで使用される条件のタイプは、コンパイラが実行できる最適化の種類を、良くも悪くも制限する場合があります。たとえば、次の場合:
uint16_t n = ...;
for (uint16_t i=1; i<=n; i++)
... [loop doesn't modify i]
コンパイラは、nが65535になり、iがnを超える以外の方法でループが終了しない限り、上記の条件により、n番目のパスループの後にループが終了すると想定できます。これらの条件が当てはまる場合、コンパイラは、上記の条件以外でループが終了するまでループを実行するコードを生成する必要があります。
代わりにループが次のように記述されていた場合:
uint16_t n = ...;
for (uint16_t ctr=0; ctr<n; ctr++)
{
uint16_t i = ctr+1;
... [loop doesn't modify ctr]
}
コンパイラーは、ループをn回以上実行する必要がないと安全に想定できるため、より効率的なコードを生成できる可能性があります。
符号付き型のオーバーフローは、厄介な結果になる可能性があることに注意してください。与えられた:
int total=0;
int start,lim,mult; // Initialize values somehow...
for (int i=start; i<=lim; i++)
total+=i*mult;
コンパイラは、それを次のように書き換えます。
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;
このようなループは、計算でオーバーフローが発生しない場合は元のループと同じように動作しますが、通常、整数オーバーフローが一貫したラッピングセマンティクスを持つハードウェアプラットフォームでも永久に実行できます。