あんにんにっき。

日々思ったことや、おこったことを記録するブログ。要するに日記。

VBAと.NETとJavaとJavaScriptとperlでの3項演算子の扱いの違い

 EXCEL2000でVBAマクロを書いていて気づいたのだが、3項演算子であるIIfの評価がtrueであっても、False側の式も評価されるようだ。
 ちょっと気になったので、他の言語ではどうなっているか調べてみた。

EXCEL2000のVBAの場合

 IIfの結果がFalseであっても、Falseの式も評価されるっぽい。

    Dim val As Integer
    val = IIf(True, 0, 3 / 0)

だと、実行時に、0除算エラーが出る。

Javaの場合

         int val = 0;
         val = true ? 0 : 3/0;

で、特にエラーはでない。valには0が入る。

perlの場合

         my $val;
         $val = 1 ? 0 : 3 / 0;

だと、Illegal division by zero が出る。ちょっと意外。

2006/09/07追記

 コメントで、perlの場合、実行時エラーではないですよ、という指摘を受けました。どうもありがとうございます。

my $foo = 0; としておいて 3 / 0 の所を 3 / $foo にするとチェックにかからないので実行できます

 とのことなので、試した結果無事正の側が帰ってきました。
以上、追記終わり。

VB.NET2003の場合

        Dim val As Integer
        val = IIf(True, 0, 3 / 0)

で、特にエラーはでない。valにはちゃんと0が入る。

C#2.0の場合

 IDE使って作るとコンパイル前のチェックが入ってしまうので、他と同じような感じでは書けなかった。
 / 0 の0を実行時に渡すようにした結果、コンパイルは通った。特にエラーは出ない様子。
 VB.NETと同じ.NETフレームワーク使っているのだから、納得の動き。

JavaSciriptの場合

        var val;
        val = true ? 0 : 3 / 0;

で、valには0が入る。

まとめ。

 今まで特に意識していなかったが、同じような3項演算子でも微妙に挙動が違う。
 式がtrueの時も、false側を評価したりしなかったり。
 最初に本格的に使った言語がVB.NETだったので、他も同じだと無意識のうちに思っていたような感じ。
 今後も、注意して使っていきたい。

ちなみに

 何が問題になったかというと、値が数値に変換できれば数値変換、できないものだったら0という処理を書く際に、

        val = IIf(IsNumeric(X), Cint(X), 0))

 と書いて、数値変換可能なときのみ数値変換しようとしたら、数値変換できない時もCIntが動いてエラーになっていたという話。え、常識ですか?そうですか。