Personal tools
You are here: Home ブログ 井上 久々にCで面白いバグ(解答篇)
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
Apache2.4のリリース予定は来年(2011年)初め(あくまで予定) inoue 2010-12-23
Herokuの発音 inoue 2010-12-20
雑誌記事「ソフトウェア・テストPRESS Vol.9」の原稿公開 inoue 2010-12-18
IPA未踏のニュース inoue 2010-12-15
労基法とチキンゲーム inoue 2010-12-06
フロントエンドエンジニア inoue 2010-12-03
ASCII.technologies誌にMapReduceの記事を書きました inoue 2010-11-25
技術評論社パーフェクトシリーズ絶賛発売中 inoue 2010-11-24
雑誌連載「Emacsのトラノマキ」の原稿(part8)公開 inoue 2010-11-22
RESTの当惑 inoue 2010-11-22
「プログラマのためのUXチートシート」を作りました inoue 2010-11-19
「ビューティフルコード」を読みました inoue 2010-11-16
Categories
カテゴリなし
 
Document Actions

久々にCで面白いバグ(解答篇)

昨日の書き込みの解答篇です。

バグのあるコードを再掲します。

// buggy code
*(const char**)apr_array_push(arr) = arr->nelts == 0 ? "foo" : "bar";

ヒントに示したK&R2の65ページには次のように書いてあります。

多くの言語と同様に、Cでは演算子の被演算数に対する評価順序は指定していない。(例外は、&&、?:と','である。)

代入演算子(=)の右辺と左辺のどちらを先に評価するかが決まっていません。バグのあるコードの場合、右辺を先に評価すると、一回目にarr->nelts==0が真になり、意図どおりの動作をします。左辺を先に評価すると、apr_array_push()の中でarr->neltsをインクリメントするため、意図どおりにarr->nelts==0が真になることはありません。

少し続きがあります。ヒントのひとつとして次のように書きました。

Javaでは(残念ながら)同じバグを起こせません

Javaは被演算数に対する評価順序を「左から右」と規定しています。しかし、本質的なバグの原因(式の中の副作用)がなくなるわけではありません。誤ったヒントでした。

Javaでも同様の問題があることをコード例で示してみます。Cのコードと似たようなコード(副作用のある式。メソッド呼び出しを含む左辺値を返す式)にしてみました。Cですら不格好なのに、Javaにすると嫌がらせとしか思えません。と言うか、Javaの方が分かりづらい気すらします。

class My {
    // Note that this is not a productive code
    private String[] arr = new String[32];
    private int nelts = 0;
    public String[] arrPush() {
        nelts++;
        return arr;
    }
    public static void main(String args[]) {
        My my = new My();
        my.arrPush()[my.nelts] = my.nelts == 0 ? "foo" : "bar";
    }
}
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/inoue/c-bug-answer/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.