こんばんは,椚座です。
On Sat, 20 Dec 2003 23:21:31 +0900
Kazutaka "Zak" Sawa <CXJ03106@xxxxxxxxx> wrote:
> 結局最後に残った問題は、以下のソースのコンパイル結果でした。
>
> for (; gDMem.SendLength != 0; )
> ;
これって,ポーリングですよね? そうじゃなければ外してますが(^^;
ループの処理として実際に書かれているコードから判断して,ループの
実行中には変化されえないと見られる変数をあらかじめレジスタに
入れておくのは,最適化の王道ではないでしょうか。変数がメモリ上に
あればあるほど(というのもおかしいですが),無用なメモリ参照を
減らして速くするために,あらかじめレジスタに入れられてしまいます。
ところが,割り込みの中などで,その場のコードからは予測できない
変化を起こしうる変数を扱うときには,このような最適化が行われては
困るので,そのために volatile というものがわざわざ用意されている
のです。なので,volatile が付いていなければ,バグとは言いにくい
のではないかと。
確かに,
for ( /* nop */ ; [変数] != 0 ; /* nop */ ) {
/* nop */
}
上記のようなループを,ループの中において [変数] が変化することは
ない場合に作っても無意味なのは明らかですから,そのぐらい正しく
判断して残しておいてくれよと言いたくなるのが人情だと思いますが。
gcc は容赦なく削っちゃいますね。
ちなみに,
int i;
for ( /* nop */ ; (volatile int)i != 0 ; /* nop */ ) ;
みたいに,キャストで局所対応することもできます。実際に volatile な
変数でやるとバグの元なのでおすすめしませんが,宣言で volatile に
するほどの volatile さではないけれど,やや volatile 気味かもって
ケースにどうぞ(どんなケースだ・・)。
Junsuke Kunugiza, jk@xxxxxxx