Home日記コラム書評HintsLinks自己紹介
 

フィンローダのあっぱれご意見番 第89回「流れる先の杖」

← 前のをみる | 「フィンローダのあっぱれご意見番」一覧 | 次のをみる →

今年の夏は水不足という声を全く聞かなかったが、 そうなるとやけに集中豪雨というか水害が多くなるというのは困ったものである。 確かに水不足と水害は排他的な現象ではあるが、水不足でない時は水害というのであるなら、 どっちに転んでも害が避けられないわけで、社会のシステムがどこかおかしすぎる。

最もインパクトがあったのは、 8月14日に神奈川県玄倉川で中州にキャンプ中の18名が増水によって流され、 13名が死亡したという事件であることで異論はないだろう。 fjでも結構盛りあがったし、FPROGでもかなり議論になった。 しかし、議論の中身はというと、どこも似たり寄ったりで、とりあえず 「キャンプの人達を強制退去させられなかったか」 「ダムの放水を止めなかったのは責任問題ではないか」 「救出の方法はなかったのか」 等が論点になっていて、議論の流れから結論に至るまで、どこを参考にしても同じようなものである。 つまり、強制退去は権限が誰にもないから無理、放水を止めるとかえって危険、 救出作業はあれで精一杯。という結論で、まとめは 「何度も警告したのに危険な場所に居るのが悪い」という所で意見が一致するようだ。

ただ、一つだけかなり気になったことがある。 それは、14日の11時41分頃、1才位の子供が付近の住民によって救出された、ということである。 報道では、たまたまそこに来ていた人という感じで、 子供が流れて来たので夢中で川に飛び込んだとか、 その人の息子が後ろからベルトをつかんでいたとか、 一瞬タイミングがずれていたら助けられなかっただろうとか、 かなりリアルなインタビューだったので、これは本当の話なのだろう。

その話を疑っているわけではない。 もちろん美談である。 ただ、海や川の事故で、溺れている人を助けようとした人が逆に遭難してしまうことがある。 今回はまさにそうなってもおかしくない状況だったが、 運良く助けた人も無事だった。 目の前を子供が流れて来たら、飛び込むしかないだろう。 そういう声もある。 そういわれると、そうかもしれない。

では何が気になるのか。一つだけ不自然なことがある。 現地には、消防団や警察など、救出隊員が到着しているのだ。 この人達はプロのレスキューだ。 しかし、子供を助けたのは、レスキューの人ではなく、通りすがりの人である。 なぜプロが助けなかったのだろうか?

中州に取り残された人達が今にも流されそうだ、 というのは報道を見ても分かる。 実は私は見損ねたのだが、 ずばり流れる瞬間まで報道されたという話がネットで流れていた。 ショッキングなのでその後の放送ではカットされたのではないか、 という説もあった。 実際そうだったのだろう。

一般論をしよう。 今にも誰かが流されそうだという状況で大至急考えなければならないのは何か。 流されたらどうなるのかということのはずだ。 それをどのように踏まえてどんな救出作戦を立てたのか、 というのが分からないのである。 あの位置から流されたらどこをどう流れるか。 これはある程度の予測が付く。 その場で完璧に救出できる自信がない限り、 流された時のことを考えて、 下流にも誰かを配置していると思うのだ。 しかも、実際に、下流には人がいて、流れて来た子供を助けているのだ。 しかしそれは消防隊でも警察でも自衛隊でもなかった。

  

もし、通りすがりの人がないければ、 もう一人死者が増えていた可能性が極めて高い、 というのであれば、これはまさにラッキーだったことになる。 じゃあ通りすがりの人ではなくて、 その位置にプロレスキュー隊員がもしいたら、もう一人位は助からなかったのだろうか?

 

※ 素人が救助できるような流れの場所なのだから、 プロならもっとうまくやれるのではないか。

というような議論はネットのどこにも見かけなかったのだが、 実際のところどうなのだろうか?

§

プログラムを組む時に、 流される前に何とかするのではなく、 流れてしまった後にどうするか、という発想が必要になることがある。 特にユーザーインターフェースを設計する時には重要である。 つまり、ユーザーは必ずいつかはミスをする。 しかし、ソフトウェアの設計時には、 ユーザーが正しい操作を行うと想定してしまいがちである。

極端な話、殆どミスをする可能性はないし、 その時の結果も致命的ではない、 ということがあらかじめわかっていたら、 その対策は何もしなくてもよいかもしれない。 他の処理を改善した方がいいかもしれない。 この種の問題は、常にトレードオフとの戦いになるものだ。

常にエラーを想定すべき処理もある。 mallocの呼出しなどが典型的なものである。 指定した量のメモリが獲得できる保証は何もないからだ。 あるいは、fopenの処理。 ファイルが開けないということは結構あるわけで、 その処理が行われていないと、fopen以降の処理が大変問題である。

なぜかエラーを想定していない不思議な関数もある。 getsだ。 getsは、 指定した領域に、長さとは無関係に読み込まれた文字を'\0'が現れるまで全部突っ込む。 指定した領域の長さは一切考慮しない。それを考慮するのはプログラマーの責任、と いいたい所だが、 おそらくgetsに突っ込む文字列の長さを決定するのは、 プログラマーではなく、 そのソフトウェアを使う人、つまりユーザなのである。

---- List ----

    char s[128]; /* 128 バイトもあれば十分だろう */

    gets(s); /* と思ったら甘い… */

---- List end ----

C言語。

そこで、getsは使わずにfgetsを使え、という定石が出てくるのである。 つまり、gets(s); ではなく、fgets(s, 128, stdin); と書いておけば、 sに何千文字も書き込もうとしても、最初の127バイトで必ず壁にぶち当たるようになる。 ただし、getsとfgetsの改行文字の扱いが違うことには気をつける必要がある。

§

  

これとは直接関係ないのだが、 私の場合、Webを見て関心を持ったページは手元にファイルとして保存することにしている。 Webというのは、TVに似た側面もあって、 その時限りの情報というのが意外とあるのだ。 本来、検索機能をフルに活かすためには、 一旦公開したデータは変更しないで永遠にそこに置いてある、というのが望ましい。 もちろん、変更するなといっても、誤り等を訂正するような更新・変更はある方がよいし、 必要に応じてページ構成を大幅に変更するのも仕方ない。 しかし、どこのページとは言わないが、 例えばほんの短期間だけ謝罪のページを見せただけで削除するような、 自分にとって都合のいいことしか見せないページというのは、 WWWのマナーとしてはいかがなものか、と思ったりするのである。

 

※ 当時の企業Webの多くがそういうことをやっていた。 ひどいのになると、 検索させたくないのか、 画像ファイルを置くだけだったりした。

余談はさておき、このようなページをしっかりファイルに保存するのはとかもく、 大量にファイルがたまってくると何が何だか分からなくなる。 Netscapeなどのブラウザで保存ディレクトリを指定すれば、確かに一覧は出てくるのだが、 所詮ファイル名である。内容が全く想像できないことも多い。 そこで、perlでちゃちゃっと処理して、 各ファイルの<TITLE>の所を抜き出して、 ローカルファイルへのリンクページを生成するスクリプト、 なるものを作成したわけである。 これだと少し使いやすくなった。 実は最近はこのリンクページもあまり使わなくなった。 というのは、namazuで検索するようにしたからである。

 

※ pc に namazu を入れてインデックスを作成しておけば、 pc 内のファイルを全文検索できる。 当時、既にそういうことができたのだ。

それで何が起きたかというと、データの処理中にperlがお亡くなりになるのだ。 原因を絞ってみたら、あるデータを処理する時に落ちることが分かった。 このデータ、改行コードがcontrol-Mだけである。

 

※ perl が control-M だけの場合に改行だと解釈してくれないのだと思われる。

理屈では長さ制限なんてないような気もしたのだが、 とにかく現実問題として、どうもperlで1行読み込むには長すぎるらしい。 perlは数百KBの1行テキストを処理することも想定して作られていただろうか?

とりあえず、テキストの1行が長すぎるのが問題だ、 というのであれば、 1行ではなくて適当な所でやめておけばいいのである。 そこで手を加えたのがList 2だ。 あまりスマートなコードではなくて恐縮だが、 見逃していただければ幸いである。 とりあえず、これは1行がもし2000バイトを超えていたら、 最初の2000バイトで処理を打ち切るという処理を追加したものだ。 なぜ2000かという根拠は全くないのだが、 これで異常終了は発生しなくなったから結果オーライである。

---- List 2 ----

  while (<FILE>) {
    $tmp_line = $_;
    if (length($tmp_line) > 2000) {
      $tmp_line = substr($tmp_line, 0, 2000);
    }
      
    if ($tmp_line =~ /<TITLE>(.*)$/i) {
      $title = $1;
      if ($title =~ /^(.*)<\/TITLE>/i) {
        $title = $1;
        last;
      }
    }

#    if (/<TITLE>(.*)$/i) {
#      $title = $1;
#      if ($title =~ /^(.*)<\/TITLE>/i) {
#        $title = $1;
#        last;
#      }
#    }

  }

§

  

玄倉川の事故、事前に警察官が警告したそうである。 告は無視されたのだ。 その結果の悲劇なのだが、 「警告を無視したんだから事故にあっても仕方ない」という意見もあるようだ。 正論である。 どうして警告を無視したのだろうか。 FPROGORGでもちょっとだけ話題になった。 私は「void main 派なので警告は無視する習慣だったのでは」と書いた。 もちろん冗談だが、 日頃からコンパイラが出す警告を無視する習慣のある人は、気をつけた方がいいかもしれない。

 

※ C言語の規格では main は int 型なので、値を返さなければならない。

(C MAGAZINE 1999年11月号掲載)
内容は雑誌に掲載されたものと異なることがあります。

修正情報:
2006-03-14 裏ページに転載。

(C) Phinloda 1999-2006, All rights reserved.