昔の最近の出来事(2011.07)

2011/07/31

AM中に起床。

地デジ対応の為にアナログTVをどかして掃除したり。

ちょろり休出。

川崎ヨドバシでTV物色。今のアナログTVを買った は50インチで50万円とかの相場だったのですが、随分と安くなってるなぁと思ったりも。 でも、地デジ放送と思われる映像が表示されているのを 近くで見るとなんだかブロックノイズがもやもやと乗ってて画質が良く無いなぁ という印象。恐らくパネルは問題無いと思うのですが、映像ソースの画質がこれじゃぁ 勿体無いなぁと思ったりも。本当にこれが普通なのかしら? あれこれ見た結果「REGZA 32ZP2」 にしてみたり。10万円ほどの買い物だったのですが、約6年前に買ったアナログTV(4:3の20Vインチ) とほぼ同じ値段で、16:9の32インチだったりフルHDだったり3D対応だったり外付けHDDを付ければ 録画できたり簡易的にインターネット接続できたりと 機能的には山盛りになってます。 TV全般的に、ここ数年の地デジ化の流れに乗っかって最頂点のコストパフォーマンス になってるんじゃないかと思ったりも。来年以降は目を引くのも難しい 家電の一つになるんだろうなぁ。
3D対応なのでPS3は今のPCモニタとのシェアからTVの方に繋ぎかえようかと思ってます。 ただ32インチは今のTV台ではギリギリです(^^; 届くのはあさってなので、それまでにもう少し部屋を片付ける必要があるかも。

gdc-0.30(dmd2.054)対応。std.regexpをstd.regex使用に以降する話。 3Dモデル形状データであるWavefrontのOBJファイルをパースするのに、 正規表現エンジンを連想配列に保持して、コマンドでそれを切り替える というコードにしてます。元のコードの抜粋は以下のような感じ。

import std.regexp;
 :
  RegExp   obj_reg_tbl[string] ;
 :
    num = "(" ~ nume ~ "|" ~ numd ~ "|" ~ numi ~ ")" ;
    obj_reg_tbl["v"     ] = new RegExp( "^v\\s+"  ~ num ~ "\\s+" ~ num ~ "\\s+" ~ num  ,"") ;
 :
    token = obj_reg_tbl[act].split(line) ;
    obj.add_vertex( std.conv.to!(double)(token[1]),std.conv.to!(double)(token[2]),std.conv.to!(double)(token[3]) ) ;

ポイントは、
という感じ。で、これを以下のよう書き換え。

import std.regex;
 :
  Regex!(char) obj_reg_tbl[string] ;
 :
    num = "(" ~ nume ~ "|" ~ numd ~ "|" ~ numi ~ ")" ;
    obj_reg_tbl["v"     ] = regex( "^v\\s+"  ~ num ~ "\\s+" ~ num ~ "\\s+" ~ num  ,"") ;
 :
    auto token = match(line,obj_reg_tbl[act]) ;
    if( token.empty==false ){
      auto capt = token.captures ;
      obj.add_vertex( std.conv.to!(double)(capt[1]),std.conv.to!(double)(capt[2]),std.conv.to!(double)(capt[3]) ) ;
 :

書き換えのポイントは以下のような感じ。

例えばCSVのような単純なテキストフォーマットをパースするのには、今のstd.regexで良いかなという 気がするのですが、ちょっと複雑な構造を持った構文のパースを行おうと思うと割と面倒くさい という予感がします。この点、RegExpの splitメソッドは勝手が良かったなぁという感想。

2011/07/30

AM中に起床。

gdc-0.30調査。 先日のSegfaultした後のバックトレースですが、無限表示を途中で停止して 最初の方を眺めてみたり。

Program received signal SIGSEGV, Segmentation fault.
0x0045d49e in _d_newarrayT (ti=..., length=1) at ../../../libphobos/rt/lifetime.d:779
(gdb) l
774	 * (For when the array is initialized to 0)
775	 */
776	extern (C) void[] _d_newarrayT(TypeInfo ti, size_t length)
777	{
778	    void[] result;
779	    auto size = ti.next.tsize();                // array element size
780	
781	    debug(PRINTF) printf("_d_newarrayT(length = x%x, size = %d)\n", length, size);
782	    if (length == 0 || size == 0)
783	        result = null;
(gdb) where
#0  0x0045d49e in _d_newarrayT (ti=..., length=1) at ../../../libphobos/rt/lifetime.d:779
#1  0x0045919f in _d_throw (obj=...) at ../../../libphobos/gcc/deh.d:153
#2  0x0048406b in onOutOfMemoryError () at ../../../libphobos/core/exception.d:461
#3  0x004aa18c in mallocNoSync (this=..., size=41, bits=8, alloc_size=0x331d8) at ../../../libphobos/gc/gcx.d:458
#4  malloc (this=..., size=41, bits=8, alloc_size=0x331d8) at ../../../libphobos/gc/gcx.d:438
#5  0x004831f0 in gc_qalloc (sz=41, ba=8) at ../../../libphobos/gc/gc.d:210
#6  0x0045d533 in _d_newarrayT (ti=..., length=1) at ../../../libphobos/rt/lifetime.d:824
#7  0x0045919f in _d_throw (obj=...) at ../../../libphobos/gcc/deh.d:153
#8  0x0048406b in onOutOfMemoryError () at ../../../libphobos/core/exception.d:461
#9  0x004aa18c in mallocNoSync (this=..., size=41, bits=8, alloc_size=0x333e8) at ../../../libphobos/gc/gcx.d:458
#10 malloc (this=..., size=41, bits=8, alloc_size=0x333e8) at ../../../libphobos/gc/gcx.d:438
#11 0x004831f0 in gc_qalloc (sz=41, ba=8) at ../../../libphobos/gc/gc.d:210
#12 0x0045d533 in _d_newarrayT (ti=..., length=1) at ../../../libphobos/rt/lifetime.d:824
#13 0x0045919f in _d_throw (obj=...) at ../../../libphobos/gcc/deh.d:153
#14 0x0048406b in onOutOfMemoryError () at ../../../libphobos/core/exception.d:461
#15 0x004aa18c in mallocNoSync (this=..., size=41, bits=8, alloc_size=0x335f8) at ../../../libphobos/gc/gcx.d:458
#16 malloc (this=..., size=41, bits=8, alloc_size=0x335f8) at ../../../libphobos/gc/gcx.d:438
#17 0x004831f0 in gc_qalloc (sz=41, ba=8) at ../../../libphobos/gc/gc.d:210
#18 0x0045d533 in _d_newarrayT (ti=..., length=1) at ../../../libphobos/rt/lifetime.d:824
#19 0x0045919f in _d_throw (obj=...) at ../../../libphobos/gcc/deh.d:153
#20 0x0048406b in onOutOfMemoryError () at ../../../libphobos/core/exception.d:461
:

ずっこけているのは _d_newarrayT()というメモリ割り当て関数の最初の所なのですが、 バックトレースを見ているとOutOfMemoryErrorで例外が飛んでいるようです。 OOM例外処理の中で、メモリを割り当てる処理をしたところ、またOOM例外が発生して.... を無限に繰り返している模様。Segfaultを踏んだ時点では何度も例外が発生した後の 為、かなり深いスタックを積んでしまっているようです。ただ、OOM時の例外処理の 方法に問題があるという事は言えそうですが、これ自体は二次的に釣れた不具合だと 思われます。何かしらの原因で例外が発生したところ、前述無限ループに飛び込んだ ものと思われますので、そもそも無限ループに飛び込む契機が何だったのかは よく判らず。

前述の件を踏まえて考えてみると、スタックダンプは有限なのかもと思い、 少し我慢してダンプを続けてみたところ、始点が出てきたり。

:
#23678 0x0048420b in onOutOfMemoryError () at ../../../libphobos/core/exception.d:461
#23679 0x004a3054 in freeNoSync (this=..., p=0x18dc280) at ../../../libphobos/gc/gcx.d:897
#23680 free (this=..., p=0x18dc280) at ../../../libphobos/gc/gcx.d:883
#23681 0x00483501 in gc_free (p=0x18dc280) at ../../../libphobos/gc/gc.d:248
#23682 0x0045dc1b in _d_delarray_t (p=0x18f0ba8, ti=...) at ../../../libphobos/rt/lifetime.d:1079
#23683 0x00401624 in __dtor (this=...) at RubiksCube.d:28
#23684 0x0045dce5 in rt_finalize (p=0x18f0ba0, det=false) at ../../../libphobos/rt/lifetime.d:1166
#23685 0x004a76e0 in fullcollect (this=..., stackTop=0x22fd8c) at ../../../libphobos/gc/gcx.d:2713
#23686 0x004a7bef in fullcollectshell (this=...) at ../../../libphobos/gc/gcx.d:2391
#23687 fullCollectNoStack (this=...) at ../../../libphobos/gc/gcx.d:1329
#23688 0x00483842 in gc_term () at ../../../libphobos/gc/gc.d:133
#23689 0x00458b3b in tryExec (dg=<value optimized out&rt;) at ../../../libphobos/rt/dmain2.d:518
#23690 0x0045926a in main (argc=2293728, argv=0x230000) at ../../../libphobos/rt/dmain2.d:568

終了時にメモリを全部開放しようとする、その途中で死んでいる模様。
gc/gcx.d を見てみると、runningなるフラグ変数が追加されていて、 fullcollect()を開始するときにrunning=1をセットし、終了したら0に 戻すという事をやってるみたい。そして、running=1になっていたら onOutOfMemoryError()が実行されるというコードが各所に散りばめられている ようです。
これらのコードを踏まえて動きを想像してみると、 二つのスレッドのそれぞれがfullcollect()を実行したが、先にフラグを 取れたスレッドは問題無くfullcollectを実行できるけど、後のスレッドは 先のスレッドがセットしたrunning=1を見たので、onOutOfMemoryError()を 実行。その中でメモリ割り当てを行ったが、例外処理中で実行されるmalloc()内で running==1ならばonOutOfMemoryError()を実行。ここが無限ループに飛び込んだ 開始点でその後無限に繰り返した後にSegfaultといったところでしょうか。

最初、fullcollect()の始まりの所にある runningフラグのセットと thread_suspendAll()の順番が悪いのかと思って変更してみたのですが 様子が変わらず。結局runningフラグを1にしないようにしたところ (これで2.053の時と動き的には同じになるハズ)、なんとなくずっこけなくなったり。
それにしても、何故このようなコードが仕込まれたんだろう?

そんな訳で手持ちコードのコンパイルテスト。概ね以下のような対応が必要そう。

  1. std.regexpが廃止される予定のワーニングメッセージが出る。std.regexを使用したコードに変更。
  2. default 無しのswitch()文がdeprecatedに。意図的にdefaultを抜いているコードは 「default : core.exception.onSwitchError() ;」とかを入れるのが良いかも?

個人的には二つ目のがなんでまた?という感じ。というのは、コンパイル時にエラー にならずに実行時に例外になるのは何故か?というのは、 以前にも考えた事だったわけですが、 その時の解釈は「内部矛盾をいい加減な方法で処理しない効果がある」という 感じでした。これ、defaultでデタラメな事をされてしまうと、かえって コードの信頼性が失われてしまうように思うのですがどうでしょう。 確かに実行時にエラーするのはもっとダメだというのは判ります。 ならば、deprecatedではなく別のオプションスイッチを設けてもらった方が 良いんじゃ?と思ったりも。
コンパイル時にチェックできる事をチェックせずに (実際にはdefaultの有無をチェックできるだけで、defaultで正しく例外処理なりを 行っている事をチェックできている訳では無い)、実行時に例外にするのは 何故なんだ?とハマった人が全員思った事に対して、意図的にdefaultを抜いた時の 効果を上手く説明できなかったのでしょうか?

それにしても、gdc 0.30の話はともかく、Web検索しても dmd 2.054の話も 全然出てこないのは何故なんだ?(^^;;;;;;;;

2011/07/29

日付越え前に帰着。

gdc-0.30のテスト。どうもスレッドを破棄するときにSegfaultを踏んで しまっている模様。ただ、gdbを使ってバックトレースを表示したところ 無限にメッセージ出力されたり。うーむ。

2011/07/28

日付越え。

gdc-0.30のテスト。なんだかdmd2.052ベースのgdcであれこれハマったのが再現 している気も。問題はなんとなく解決できたような気がしていたパッチが効いてないところ。 うーむ。

2011/07/27

日付越え。

gdc-0.30のビルド。先日のは予定通りICE落ちしていたり。libphobosの std/file.dのコンパイルがダメらしい。-O2を外してそのソースだけコンパイル。 そしてmakeでビルドを続けたり。で、最後まで通ったのでmake installしてみたり。

手持ちソースをビルドしてみたところ、「std.regexpは8月に廃止される予定だからstd.regexを 使ってね」というワーニングメッセージが出たり。うーむ、std.regexって Rangeを使ってるのでなんだか扱いにくいんだけどなぁ......

で、dmd2.053ベースのgdcに引き続き、単スレッドのWinアプリは大丈夫ですが、 マルチスレッドなのがダメっぽい感じ。dmd2.052,2.053ベースのgdcと同じく libphobos/rt/lifetime.d と libphobos/core/thread.dの自作パッチを当ててみたり。 でもなんかちょっとダメな感じも。

2011/07/26

日付越え。

gdc-0.30をビルドしてみることにしたり。MinGWビルドだとビルド中でICE落ち するようですが、最適化オプションを変更すればいけるようなのでひとまず それで。ICE落ちするまで見ていられないので、ビルドを仕込んで寝たり。

2011/07/25

日付越え。

先日dmd2.054対応されたgdcですが、その数時間後に v0.30という gdcのバージョンが打たれたようです。ただ、いくつか問題が報告されている模様。 MinGWでのビルドも問題があるようなので少し様子見。

2011/07/24

AM中に起床。そしてエアコンが不調。

アナログTV放送の最終回。カウントダウンで12:00と同時にブルーバックの 案内画面に切り替わったり。そんな訳で来週にでも地デジ対応TVを物色しようかと 思ったり。

久々のHome。3月末に行われる予定だったマクロスFのライブが行われるという事で 観てみたり。30分前くらいに移動を試みたのですが、物凄い人数が移動している 為か、「このラウンジは満員です」攻撃を2回ほど食らったり。ナビゲータからの直接 移動がダメなのか?と思い、スクウェアから移動してなんとか潜入成功。で、 ダウンロードに10分ほど要してライブ開始。一言で感想を述べると「正直驚いた」です。 映画のシーンを模したと思われるモーションでリアルタイムレンダリングしていたり、 楽曲も5曲ほどあったり、イベントシーンもあったりと、こんな事できるんだという のが正直な感想です。恐らく4ヶ月延期された間にチューニングしたんじゃないかな? と推測したりも。

dmd2.054ベースのgdcが来ている模様。 今回は少し出てくるのが遅いなぁ?と思っていたのですが、変更量がなにやら凄い事になってます(^^; お疲れ様です(ここに書いても伝わらないですけど)。 今回は変わりすぎているようなので 色々突っかかる可能性が高そうな予感。見た時点で1時間前にコミットされたばかりのよう なので、一日ほど置いてからビルドを試してみようと思います。

そういや今日の後半は携帯のワンセグでTVを観ていたのですが、ずっと付けている と思いのほか発熱していたり。ワンセグとは言え映像デコードは負荷の高い処理 なのかもと思ったりも。

そして24:00きっかりで全チャンネル砂嵐に。そういやデジタルになると 砂嵐を見る事も無いかもなぁと思ったりも。

2011/07/23

昼前起床。

涼しいなぁと思っていたら午後から急激に温度上昇。

手持ちコードのバグ調査。一度読み込みに成功したファイルが、別の操作を した後に再度読み込みしようとするとファイルが見つからなくてエラーすると いうもの。読み込みを行うファイルはテストコード内で、ファイルをパス指定無し で(つまりカレントディレクトリのファイルを)オープンしてたのですが、 GetOpenFileName()でファイルダイアログを開いて別のファイルを読み込んだ後に、 再度パス指定無しで読み込もうとすると失敗するという感じ。 カレントディレクトリを表示させてみたところ、変更されている事が判ったり。 dmd2.052ベースのgdcからこんな感じだったようですが、これってこういうもんだっけ?

Webで検索してみるとGetOpenFileName()の有名な挙動らしい。現在使用しているgdcは MinGWビルドの為、phobosのファイル操作はWinAPIを使ったものが多い感じになってます。 以前使っていたgdc(dmd2.014ベース)のphobosと挙動が変わったのかもなぁという想像。 で、カレントディレクトリが気づかない間に変わると色々と具合が悪いので 適当な方法で対処したり。

2011/07/22

日付越え。

もそもそとSubversionインポート作業。Meadowでの編集作業がメインとなるので、 psvn.elを使ってみてます。dsvn.elというのもあるようですが、いざとなったら メニューバーでコマンドを探せるpsvn.elの方が個人的には良いかな?という感じ。

2011/07/21

日付越え。

手持ちコードをSubversion管理する練習をしてみたり。

2011/07/20

日付越え前に帰着。

ちょろり調べ事。

2011/07/19

日付越え前に帰着。

ちょろっとWeb散策して終了。

2011/07/18

AM中に起床。

アナログ放送の最終回を観る為に我が家はまだ地デジ対応TVを導入していないのですが、 CM時に「御覧のアナログ放送は7/24に観られなくなる....」というのが入る時があります。 「御覧のアナログ放送」という事はデジタルTVの場合は何が放送されているのだろう? と思い、ワンセグを付けておいてその時の放送を同時に見てみたところ、デジタルTVの 方では地デジ化完了のCMが流れていたり。
それにしても、1年前にレターボックス化された 時から思っていたのですが、1年経った今でも未だCMに至っては4:3のものが残っているのは 何故なんだろうと思ったりも。

2011/07/17

昼頃起床。

テトリス。ゲーム内実績を消化してみたり。厳しかったですがどうにか クリア。トロフィーもオンライン系以外のを取得できてみたり。 オンラインも少しだけやってみたり。勝てる時は楽勝だけど、勝てない時は アッサリ終了する感じ。ちょろっと繋いで相手が居れば遊べるというのは 手軽で良いかも。

2011/07/16

起きたら午後もいい時間。寝すぎ。

テトリスやったり。少しコツが掴めてきた気も。バリエーションは 追いつけるのと追いつけないのとの差が激しかったり。

2011/07/15

日付越え。

DMDの2.054が出てる模様。

2011/07/14

遅めに帰着。

ちょろりコーディング。

2011/07/13

遅めに帰着。

D言語でウインドクラスを実装したときの話」 をちょこっと更新。

2011/07/12

遅めに帰着。

テトリス。気づくと時間を吸われていたり。

2011/07/11

遅めに帰着。

テトリス。ちょっとだけのつもりが何度もやってしまう罠。 回しているとなかなか引っ付かないのも慣れてくるとなんだか面白くなってきたり。 レベル15だとどうにも追いつかない感じなのですが、むしろ慣れてくると レベル1あたりの落ちるのが遅いのよりも、そこそこの速度で落ちてくるのを せり上がりなどを利用して位置あわせする方が楽な気がしたりも。気のせいかも 知れませんが。

2011/07/10

昼前起床。昨日久しぶりに出歩いたので体が痛いです(^^;;

冷却の件。電源の方に比較的大きなファンが付いていたのですが、 この風を使えば良いじゃんと思ったり。という訳で電源を置く向きを 逆にしてみた所、今までよりも冷える感じになってみたり。

PS®Storeが全面復活していたので色々物色。お詫びのプレゼントゲームは 残念ながら全て所有しているものだったので特に嬉しい事は無く。

そんな訳で海外のStoreでは出ていたEAのTETRISが、ローカライズされていたのを 買ってみたり。 ダウンロード専販のゲームとしては定番的なゲームだと思うのですが、 こういう基本的なのが今まで出ていない所は穴かも知れません。 そんな訳でやってみるのですが、ホールドとかなかなか引っ付かない テトリミノとか、昔やったのに比べると随分と操作感覚が違っているなぁ と思ったり。落下位置表示のゴーストに惑わされたり、3個先の Nextテトリミノを次のテトリミノと見誤ったりと、視野の狭さが露呈して います(^^;
そういや以前「ゴミ箱」をやったとき、下を押すと早く落ちて、上を押すと 叩きつけるように強く落とすという操作だったのを、「なんか逆じゃないか?」 と思ったのですが、今回のTETRISでも下を押すと早く落ちて上を押すと落下位置に 瞬間移動するという操作でした。これが最近の落ち物パズルの標準操作なのか なぁと思ったりも。そういや、ぷよぷよとかもダウンロード専販で出せば良いと 思うのですが何故か出ないんですよね。

テトリスのWikipedia を読んでみると、最近(と言っても2002年以降ですが)はガイドラインなるものが 存在しているらしい。 テトリミノの形と色の対応ついてもガイドラインに示されている ようで、確かにEAのはガイドラインに従った色付けになってるなぁと思ったり。 早く落とす時の操作もガイドラインに準拠した仕様みたい。

2011/07/09

昼前起床。

蓋を開けて調査。ひとまず電源を交換してみようと思ったのですが、そもそも どういう仕組みになっているのかさっぱりだったのでWebで調べて実物を 確認したり。スリムタイプのデスクトップの為、小型のマイナーな電源を 使っているのに少々困ったりも。ひとまず普通のATX電源とやらで良さそうなので、 それで電源が悪いのか否かを切り分けてみる事に。

で、もの凄く久しぶりに秋葉原に。ヨドバシで少し物色してみたのですが、 小さいのはやたら値段が高いので、蓋が閉まらないの覚悟で4500円くらいの いわゆる普通サイズくらいのを購入。基本、自作向けに部品をそろえている 為か、700Wとかそんなの誰が使うんだ?と思うようなのばかり置かれてました(^^; 他にもテスターとかナイロンバンドとか、念の為のBIOS用のリチウム電池とかも 購入。

元の電源を少し調べたり。常駐電源は出ているよもよう。でもダメっぽい。 そんな感じなので買ってきた電源に繋ぎかえ。うーむ、マザーボードやCPUの 電源ケーブルが短か過ぎて、蓋が閉まらないの確定です。で、電源オン..... うん、問題無く立ち上がりました(^^)v
蓋が閉まらないのは仕方無いのですが、完全に開けっ放しにするのは 風洞的に問題があるので、ダンボール板で蓋をしてみたり。カッコ悪ぅ(^^;; でもこれ、隙間だらけなので冷えないかもなぁ。

そんな訳で、新しいPCの購入を検討しようかなぁと思ったりも。

そういやFedoraマシンのディスプレイは16:9のを繋いでます。これは今の メインマシンに付属していたものでした。でも、Fedoraマシンのビデオカードは Voodoo3の為か、解像度選択は4:3のバリエーションしか出てこなくて、なんでも かんでも横長に表示されてました。 半ばそういうもんだと思っていたのですが、なんとなくビデオドライバに Voodoo3の選択肢があったので、それを選んでみたところ16:9表示の選択肢が 現れました。そもそも16:9画面に映す事の無い時代のビデオカードなのですが、 ハード的にちゃんと表示する仕組みが入っていたという事に少し感心しました。

2011/07/08

遅めに帰着。

PS3でWeb検索するのは複数のウインドを開こうとすると少し不便なので、 PentiumIIIのFedoraマシンを使って調べたり。

数週間前から電源が入りにくくなっていたという症状から見て、 コンデンサ系の壊れかなぁ?と推測。となると電源ユニット自体の 壊れだろうと思ったり。

2011/07/07

遅めに帰着。

やっぱりPCの電源は入りません。PS3でちょろっとWeb検索して、同じような故障例が 無いか調べてみたり。

2011/07/06

遅めに帰着。

とうとうPCの電源が入らなくなりました(激汗;;;;;;;;;

2011/07/05

遅めに帰着。

ちょろり調べ事。コードの整理。

2011/07/04

遅めに帰着。

ちょろり調べ事。コードの整理。

2011/07/03

AM中に起床。

Webで調べごとをしたりぐうたら。それにしても暑くてグッタリです。

テレ朝で土曜の深夜に放送されている「ブラマヨとゆかいな仲間たち アツアツっ!」 のスペシャル番組が午後に放送されてました。前半は大御所声優に色々聞いてみる感じ だったのですが、その中でドラえもんのアニメには日テレ版というのがあり、 ドラえもんは野沢雅子(正確には途中かららしいですが)、ジャイアンは 肝付兼太(テレ朝版のスネ夫役の人) の両氏が声をあてていたというのを初めて知って、 へーーーーと思ったり。 「ドラえもん 日テレ」でググると動画がいくつか出てきます。 Wikipediaも存在しており、 封印状態になっている理由について触れられています。

2011/07/02

起きたら午後もいい時間。寝すぎ。

そういや演算順序について。例えば、

  if( x<0 || x>=width || y<0 || y>=height || ary[x][y]==0 ){ なんかする ;}

みたいな場合。以前、物の本で「論理ORの評価順番はコンパイラ依存」という事を 読んで、ふーん と思ったのですが、前述例で「ary[x][y]==0」を先に評価して しまうと、最悪Segfaultになってしまう可能性が考えられます。なので、

  if( (x<0 || x>=width || y<0 || y>=height) || ary[x][y]==0 ){ なんかする ;}

みたいに範囲チェックの方が先に評価されるようにコントロールする必要がある かなぁと思ったりも。因みに、Webで少し調べてみると、同じ演算順序であれば 左から評価され、論理ORの場合は左側の項で条件が満たされれば、それより右の項は評価 されないという感じなので、ary[x][y]==0が一番右にある場合には括弧は無くても良いかも。

ただ、「同じ演算順位」の物を括弧で優先付けするのは、訳が判らないと言われれば その通りかも知れません。数学は得意だがプログラムの事は全く判らない人に、この事を説明 しようとすると物凄く困ると思います。そもそも、xとyが範囲内に入ってなければ 参照を許されないary[x][y]を含む項を同じ演算順位の項に含めるのは変と言われればそうかもなぁと いう気もします。もし 演算順位の意味を変じゃないように書くのであれば、

  if( x<0 || x>=width || y<0 || y>=height ){
     なんかする ;
  }else{
     if( ary[x][y]==0 ){ なんかする ;}
  }

が正しいかもなぁと思ったりもする訳です。でも、こう書くと冗長部分が生じるので、 見る人が見ると「ダメなコードの例」とか言うかも知れません。

  if( x>=0 && x<width && y>=0 && y<height ){
     if( ary[x][y]==0 ){ なんかする ;}
  }

で、見た目は少しマシになります。でも、例えば弾幕シューティングゲームの当たり判定コード を書いた事のある人の場合、性能的に「論理ANDで判定するなんて 無いわぁ」と思うかも 知れません。

そんな訳で、何を優先するかによって正解が変わるのかもなぁという結論。もし、 例のコードで 誰に対しても「これだ」と思わせる書き方があれば教えて下さい。

暑さでぐったりしながら、ひとまずここ二週間で作ったものを置いてみました (へっぽこリバーシ)。御参考まで。

2011/07/01

遅めに帰着。

もののけ姫を観終わった所であまりの眠さに急速停止。


TOP PREV