じゃんぬねっと日誌

ネタと雑記と時々プログラミング

目次

Blog 利用状況

ニュース

不況すぎる件。

スポンサードリンク

運営サイト

  • C# と VB.NET の入門サイト

書庫

Coding Horror 04

これも「コーディング ホラー」というよりは、バグです。
またもや、VB で発見しました。

VB6 以前 (コーディング ホラー)

    If obj Is Nothing = False And obj.Value <> "" Then
        Call UpdateHoge(obj.Value)
    End If

VB の AndOr は、ショートサーキット評価ではありません。
このソースの場合、最初の Nothing の評価の結果に関わらず、次の Value メンバが長さ 0 の文字列かどうかの評価を行います。

ひとことで言えば、最初の Nothing の評価が無意味になります。
つまり、obj が Nothing だった場合は、容赦なく実行時エラー (例外) が発生するということです。

VB6 以前の場合は以下のようにネスト (入れ子) させるか、

VB6 以前 (Not コーディング ホラー)

    If Not obj Is Nothing Then
        If obj.Value <> "" Then
            Call UpdateHoge(obj.Value)
        End If
    End If

ガード句を使うことになります。(以後の処理が不要な場合)

VB6 以前 (Not コーディング ホラー)

    If obj Is Nothing Then
        Exit Sub
    End If

    If obj.Value <> "" Then
        Call UpdateHoge(obj.Value)
    End If

VB7 (VB2002) 以降では、AndAlso または、OrElse を使うことで、ショートサーキット評価ができるようになりました。

VB.NET 以降 (Not コーディング ホラー)

    If Not obj Is Nothing AndAlso obj.Value <> String.Empty Then
        Me.UpdateHoge(obj.Value)
    End If

私の場合、AndOr は、論理積や論理和などの演算にくらいしか使いません。
VB.NET 以降でも、AndAlsoOrElse を使うことがないくらい、1 行で 1 評価を意識しています。

コーディング ホラー記事へのリンク

投稿日時 : 2006年7月11日 11:02

コメントを追加

# re: Coding Horror 04 2006/07/11 17:40 名無しぃシャープ

CからVBに以降した時にやっちゃったなぁ。○| ̄|_

# re: Coding Horror 04 2006/07/11 17:57 R・田中一郎

AND や OR を使う場合、最初の評価式の後に次の式に・・・と、つい勘違しがちですよね。

僕もタマネギプログラマーだった頃(今もか?)に、よくやっちまいました。

常に、二つの式を評価することを前提に考えると、入れ子にした方が効率が良い場合も多々ありますね。

基本的に、AND や OR は、僕も多用は避けています。

# re: Coding Horror 04 2006/07/11 21:55 NAL-6295

IIFでもたまに見かけますね。
その手の間違い。
ちゃんと、働きを理解していない証拠で、こんなコードが仕事で使われているとなると怖いです。

# re: Coding Horror 04 2006/07/12 13:56 ぽぴ王子

自分もじゃんぬさんと同じく、あいまいな時は If を入れ子にして1行1評価にし
ます。
とりあえず3ヵ月後の自分へ向けて手紙を書くような感じで :-)


昔は何も考えずによく書いていて、たまたまそれがバグになることはなかったで
すが(いま考えるととても怖い)、ショートサーキット評価を初めて知ったとき
は Ω ΩΩ<ナ、ナンダッテー てな感じでした。

# re: Coding Horror 04 2006/07/13 11:29 じゃんぬ

>R・田中一郎さん
バグの温床になりやすい要素を持っていますから、
ビット演算以外では使うべきじゃないでしょうね。
個人的には、「一貫して使用しない」とした方が、素直だと思います。

ネストを心配して And や Or を使用する前に、
その評価式は冗長でないかを見た方が良いでしょうね。

> 常に、二つの式を評価することを前提に考えると、
> 入れ子にした方が効率が良い場合も多々ありますね。

先のは Nothing の評価があるため例が悪かったのですが、
ネストする場合は、評価の順番を考えないと効率は良くなりません。
偽になりやすいものを、最初に評価しておくのが良いでしょう。

最近の言語はガード句を使うことが推奨されていますから、この限りではないです。

# re: Coding Horror 04 2006/07/13 11:33 じゃんぬ

>NAL-6295 さん
IIf でとなると、イコール可読性も考えていないことになりますね。
(評価の正当性を考えられない方に、それを求めるのも酷ですが)

IIf は、単純な評価式でないと使用してはいけないでしょうね。
IIf を、「評価結果を 1 行に縮められる魔法の言葉」と誤解されている方が多いようです。

私は三項演算子は使いますが、IIf を使うことはありません。
戻り値の関係上、どうしても許せないでいます。
似たようなものが続くのであれば、Math.Min メソッドや Math.Max メソッドのような、
戻り値の型が明示化された自作メソッドを作ります。

# re: Coding Horror 04 2006/07/13 11:35 じゃんぬ

>ぽぴ王子さん
個人的には曖昧でなくとも、効率をあげるためにネストさせることをお勧めします。
前述のように、一貫していた方が可読性も良いです。

# ところで、VB.NET で AndAlso、OrElse を使用する場合は、
# 括弧で括って頂かないと、どうも安心できません...

タイトル  
名前  
URL
コメント