コンパイル時に最適化はいつもチェックを外しているのですが
それでも下記のソースが最適化?により正常に機能しません。
※関数の中は簡略化しています。
関数が正常に呼ばれれば iは 2なのですが 1が返ります。
最適化の有無に関係無く
True と or を取る場合は左式で結果が確定なので
関数はスルーされてしまうのでしょうか?
もちろん
f := DelphiTest(i) or f;
に変更すれば動作します。
そういうものナノでしょうか?
環境 Windows10 Delphi2007
procedure TForm1.Button1Click(Sender: TObject);
function DelphiTest(var i : Integer) : Boolean;
begin
i := i + 1;
result := true;
end;
var
f : Boolean;
i : Integer;
begin
i := 0;
f := False;
f := f or DelphiTest(i);
f := f or DelphiTest(i);
//
end;
これはショートサーキット評価によるものです。
1回目の f := f or DelphiTest(i); では右辺のfがFalseですのでDelphiTestを呼び出さないと右辺全体が確定しません。しかし2回目は右辺のfがTrueですのでこの時点で右辺全体がTrueに確定しますのでDelphiTestを呼び出しません。
詳細は
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/JA/html/devcommon/expressions_xml.html
の完全な論理評価とショートサーキット論理評価をご覧ください。
この現象はショートカット評価だったのですね。
{$B+} 指令をコードに追加
で完全評価になるようですが
今後のバグにも繋がりかねませんのでフラグの演算と関数呼び出しは別々にしたいと思います。
HFUKUSHI さん
ありがとうございました。