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

フィンローダのあっぱれご意見番 第86回「直接コミュニケーションの時代」

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

いわゆるパソコン通信が世の中で流行り始めた頃、 双方向のコミュニケーションだとか、 マスコミのフィルターを経由しない直接の情報だとか、 特別なメディアを持たない人達が情報を公開するためのニューメディアと言われた。 というか、私もそれを強調した。 最近はその役割は主にWWWに移行しているようだ。 とはいえ、パソコン通信の方も、 サロンとしての交流の場として健在である。 場が多様化したのだと思うが、今となっては、こだわらずにあれこれ言える場、 という性質の方が重要なのかもしれない。

マスコミ等の編集者を経由しないということが重要な意味を持つことがある。 最近興味を感じたのが2件ある。 まず、オウム真理教関連のページ。 5月から6月頃、警察が信者を逮捕したり、教団施設を強制捜査したことがあった。 当然、マスコミはこれを報道した。

ところが、オウムのページを見ると、マスコミが報道しないような画像が出てくるのである。 この落差が凄いのだが、それはさておき、 警察は、ビラを何十万枚も押収したのに対して、 オウム側はそのビラをスキャナで取り込んだ画像をインターネットで公開した。 結局、情報は世界中にばら撒かれるわけである。 しかも、「これが押収されたビラだ」のようなアピールが付いてしまって、 Webへの公開を後押ししたのが警察ということになるのが、 何かシナリオ通りという感じがして釈然としなかった。

  

もう一件は、ある人がビデオデッキを修理に出したところ、 某家電メーカーの応対が極めて不満だったという話。 そこまでなら誰でも経験がありそうなものだが、 この人は、そのメーカーとの電話応対の内容を録音して、 RealPlayerで聴ける状態でWebに公開したのである。 実際、私もその内容を聴いてしまったのだが、 いやまあ凄い内容で、これが本当にそのメーカーの電話応対なら、 ちょっと今後は製品を買う気がしないという代物。 勝手に電話の内容を録音して公開しても法的に問題はないのか、 という疑問はあるわけだが、その結論はともかく、 問題もあるわけだが、実際にそれが出来てしまう時代になっているというのが凄い。

 

※ 誤解を恐れずに書かせていただくなら、 明らかに脅しているような口調だった。

このような一次情報は誰でも見ることができる。 もちろん、気が付けば、の話ではあるが。 さらに、掲示板のような場があって、自由に意見を 表明できることもある。 いま紹介した2例は、掲示板が実際にあった。 ここに集まる意見もまた面白い。意外と意見が分かれるのである。 これが関係者による工作だったらさらに凄い話なのかもしれないが、 ざっと見た感じでは、どうも単なる一般参加者というか、 当事者でない無関係の人のただの感想のようにも見える。 例えばビデオの応対の件だと、 客側のやり方がヘタだったのじゃないか、というような意見が出ていた。 そう言われればそんな気もするのである。

§

  

6月号の文字コードの特集、 正直言ってかなり自信がなかったのでどうなることかと思ったのだが、 文字コードとは全然関係ないC言語のところで大ボケをやっている。 実はこのご指摘はニフティサーブで頂きました。 ありがたいことである。 一読者がこのような情報を編集部まで伝えるというのは、大変面倒なことだと思うのだが、 メールという手段は予想以上に便利なものである。 ただ、今回はフォーラムの会議室でのご指摘だった。

 

※ ニフティサーブ: パソコン通信サービス。 フォーラムというコミュニティで、 議論が活発に行われていた。

§

とか言っている場合ではないようだ。 一つ極め付けのボケだった所を紹介する。6月号ではList 3に該当する処理である。

---- List 1 ----

    while (*to++ = *from++ || *to++ = *from++)
        ;

---- List 1 end ----
  

これはひどいという評があったのだが、 実はコンパイルできないので安心だったりする。 なんでこういう間違いをやったかというと、 簡単に言えばテストランどころかコンパイルもしないで原稿にしたのが間違いなのだが、 おそらく、 通常はこういう所には代入を書かないで、比較する時の定石、

 

※ コンパイル時にエラーになる方が、 実行できるバグよりはいい。

---- List 2 ---

    while (*to++ == *from++ || *to++ == *from++)
        ;

---- List 2 end ----

のような処理と混同したのかもしれない。 それにしても、この処理も一体何がやりたいのかさっぱり分からない。 さて、本当は何がやりたかったか考えてみると、 2バイト単位で代入していけばよいのだから、List 3 のような処理を思い付く。

---- List 3 ----

while ((*to++ = *from++) | (*to++ = *from++))

---- List 3 end ----
  

List 3のループが終了する条件は、両方とも代入した結果の式の値が0、ということになりそうだが、 おっとどっこい、この処理は本当によいのだろうか? 何となくうまく行きそうな気がするかもしれないが、 シーケンスポイントを忘れている。 つまり、C言語の規約としては、List 3のwhileの条件判断部分、 (*to++ = *from++) | (*to++ = *from++) という式にはシーケンスポイントが存在しないのである。 従って、規約上は、評価の順序が左の*to++、右の*to++、左の*from++、右の*from++、 のようになったとしても全然構わないことになる。 これでは予期した結果が得られない。 もっとも、 この処理を実際にやってみれば意外と期待通りになってしまう可能性は高い。 しかし、間違いは間違いである。 もし「|」という演算子がシーケンスポイントになれば話は簡単なのだが。

 

※ C言語は、文は出現順に処理されるが、 文の中に出現する式の評価順序は、 特定の演算子が出現しない限り、どこから行われるかわからないことになっている。 この「特定の演算子が出現」した箇所のことをシーケンスポイントという。 その箇所の前後の評価順序が確定するのである。

「|」とは違って「||」であればシーケンスポイントは存在する。 だから、List 4は文法的には正しい。 しかし、これは期待通りの動作にならない。 左の代入が終わった時点で値が0でなければ、 次に処理されるのは、やはり左である。 右の代入は、左の代入が0になるまで一度も実行されないのである。 これでは2バイトずつ処理したことにならない。

---- List 4 ----

    while ((*to++ = *from++) || (*to++ = *from++))
        ;

---- List 4 end ----

では一体どうすればいいかというと、 こういうのを思い付いたというのがList 5である。 ただ、私はこんなコードは見たことがない。

---- List 5 ----

    while ((*to++ = *from++) ? (*to++ = *from++), 1 : (*to++ = *from++))
        ;

---- List 5 ----

ポイントは三項演算子である。 「?:」の場合、「?」の左を評価した所でシーケンスポイントが存在する。 つまり、これで文法上もokだし、処理も期待通りである。 期待通りなのだが、いまいちどころか猛烈に違和感がある。 こんな書き方をする位なら、List 6のように書いた方がよほどすっきりする。

---- List 6 ----

    for (;;) {
        char c1, c2;
        *to++ = c1 = *from++;
        *to++ = c2 = *from++;
        if (c1 == 0 && c2 == 0)
            break;
    }

---- List 6 end ----

と思ったのだが、全然すっきりしていない。 終了条件があるのならdo~whileにしてList 7のように書きたいところだが、これはまずい。

---- List 7 ----

    do {
        char c1, c2;

        *to++ = c1 = *from++;
        *to++ = c2 = *from++;
    } while (c1 || c2);

---- List 7 end ----

なぜなら、c1、c2がスコープの外に出てしまうからである。 これではエラーになってしまう。 もっとも、この問題はc1とc2をブロックの外に出すだけで解決する。 何か他の問題が追加されそうで、イヤな予感がするが、まあ仕方ない。 でも、一時変数を使って構わないのなら、そもそもList 8 のように書けばいいのである。

---- List 8 ----

    while ((*to++ = c = *from++), (*to++ = *from++) || c)
        ;

---- List 8 end ----

しかしこれもいまいち面白くない。 結局shortで処理するというのが楽。 そこでやっと思い出すのだが、 2バイト文字コードを終了を意味する時のみ0が現れるように決めておくという前提があれば、 List 9 のように書けばよい、という訳で解決したような気がするのだが。

---- List 9 ----

while ((*to++ = *from++) && (*to++ = *from++))

---- List 9 end ----

§

誤りを皆無にはできないという考え方は、とりあえず主流だと思う。 しかし、不可避だからバグはあってもよい、という意味ではない。 ミスがあれば、その後に訂正する方法が確立していることが望ましい。 雑誌の記事が誤っていた場合、修正記事を出すというのが一つの方法である。 しかし、読者が修正記事を見落としてしまうことも考えられる。 こういう場合も、やはりインターネットが威力を発揮すると思う。 つまり、最終形態の原稿をインターネットで公開すればよいのだ。 何かに使う場合は、そこに公開されている情報が最も信頼できる版だと考えるのである。

  

もちろん、間違いは極力少なくすべきであることは議論の余地がないし、 文字コードの特集のような場合は特にそうであるべきだと思う。 ただ、大雑把な考え方として、 著者と読者のような、情報発信者と受信者が直接コミュニケーションできる 仕組みが折角あるのだから、それを使って最終的な品質を高めるということにすれば、 最初の版の完璧さには極端にこだわらなくてもよい、 という時代が来てくれるかもしれない。間違えるのが得意な私は、密かに期待している。

 

※ 間違いを少なくするためのコストも考慮するなら、議論の余地が出てくる。

ところで最近,実はこの連載の回数があ っていないのではないか,という気もする のだが,これまた「こだわらない」ことにす る(編注:’98年9月号より,連載回数が 違っておりました。お詫びいたします)。

 

※ 気づかない当方も大雑把すぎる。

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

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

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