ラベル golang の投稿を表示しています。 すべての投稿を表示
ラベル golang の投稿を表示しています。 すべての投稿を表示

2011年5月30日月曜日

C言語の未定義動作と golang

LLVM の blog  What Every C Programmer Should Know About Undefined Behavior を読みました。C言語の未定義動作と、最適化過程において一見正しそうにみえるバグを生み出す例が載っています。
例としてあげられているのは、符号付き整数のオーバーフロー。負の最小値(INT_MAX + 1 => INT_MIN)になると思いがちですが、C言語では未定義となっています。未定義ということなので、データが飛ぼうがコンピュータが爆発しようが文句は言えません。言い換えるとコンパイラが好きなように扱っても良い(標準準拠)ということになります。以下例を見ていきます。

int i, n; for (i = 0; i <= n; ++i) は n = INT_MAX のときに無限ループしそうな気がしますが、INT_MAX + 1 は undefined なので、コンパイラは n の値に関わらずループは n+1 回実行されると解釈し、コードを最適化することが可能です。
このことがバグを誘発します。void f(int n) { /* check overflow */ if (n > n+1) abort; ... } というコードがあったとき、n < n+1 によりオーバーフローチェックがされているように見えますが、 INT_MAX+1 は未定義なのでコンパイラは n > n+1 は常に偽と解釈することが可能です。その結果、if文は取り除かれてしまい、プログラマの思い通りには動作しません。

さて golang ではどうでしょうか?LLVM blog で挙げられていた以下の項目について mailing list に質問してみました。
  • Use of an uninitialized variable 
  • Signed integer overflow 
  • Oversized Shift Amounts 
  • Dereferences of Wild Pointers and Out of Bounds Array Accesses 
  • Dereferencing a NULL Pointer 
  • Violating Type Rules 
お返事を頂いた結果としては、すべての動作は定義されているということでした。
GoはCよりプログラマが思ったとおりに動く言語であると言えるでしょう。

2011年5月29日日曜日

Goroutine on App Engine

先日、待望の App Engine 上での Go 言語サポートが発表されました。
Goroutine は single thread 上で実行されるということですが、Multi-threading が利用できない他のプラットフォームと比較すると、並列性サポートが非常に楽になったと言えるのではないでしょうか。

早速 goroutine を試してみます。

以下のコードでは 3 つの goroutine が 1ms ずつ sleep しながら 5 つ数えます。(w を引き回すのは良くないかも?)



実行したときの出力結果は以下のようになりました。

Routine 0: 0
Routine 1: 0
Routine 2: 0
Routine 0: 1
Routine 1: 1
Routine 2: 1
Routine 0: 2
Routine 1: 2
Routine 2: 2
Routine 1: 3
Routine 2: 3
Routine 1: 4
Routine 2: 4
Routine 0: 3
Routine 0: 4
Done.

各 routine が interleave されて実行されている様子がわかります。
App Engine では並列性の弱さが一つの弱点である/あったと思いますが、goroutine が動作することにより楽に並列性を確保することができます。
現在 go runtime は申し込みしないと appspot.com 上で使えません。私も今申し込んでいるところです。上記のサンプルはローカルで動作させていますが、appspot.com 上でも同様に動作すると思います。

はやく experimental を抜けて実用出来るようになってほしいです。