引数渡し、ガーベッジコレクション

プロキシ作ろうと思ってたが、気合が入らず、かわりに「C++の設計と進化」を読み進める。

9章に面白いことがかいてあった。

言語は、変数に関して、SmallTalkやModula-3のような参照のセマンティクス(名前がメモリのどこかにあるオブジェクトを指すポインタであること)を持つべきか? それともCやPascalのような本物のローカル変数をもつべきか? この問いは重要である。(中略)Simulaはクラスオブジェクトに対して(のみ)参照を使い、内臓タイプにはローカル変数を使うことによって、この問いから逃げた。参照と真のローカル変数−−関数のためにスタック上に確保されるローカル変数がオブジェクトの参照(アドレス値)ではなくオブジェクト本体であること−−の両方のメリットを、醜さなしで言語が提供できるかどうか、これはいまだに結論が出ていない問題だと私は思う。

ちなみに、Simulaとは、オブジェクト指向の原点と言われている言語。C++もこれを出発点としている。少し調べてみたのだが、40年前の言語なので、構文もわけわからなかった。話によると、call-by-name, call-by-value, call-by-referenceの三種類の引数渡しが駆使されているらしい。この他には、call-by-sharingと言われたCLUという言語もJavaと似たような引数渡しの言語のようだ。

その他。

Stroustrup先生がガーベッジコレクションに好意的なのが意外だった。スマートポインタなんか使わずに、ガーベッジコレクション用のライブラリ使った方が良い場合が多いみたいなことも言っていた。僕が、今のところのスマートポインタを使いたい理由が、(1)例外安全性の確保(例えば、コンストラクタ中の例外など)と、(2)コンテナにポインタを入れたい(でも削除時にメモリリークしたくない)ということなのだから、ガーベッジコレクションでも良いわけか。

しかし、「C++ガーベッジコレクションを導入する」と上司に言ったら、嫌な顔をされる可能性100%だ。「ガーベッジコレクションがある=プログラマが怠ける=だからJavaは遅い」と考える人が世の中には多い。

話が少し変わるが、この本のどこかに、C++上にガーベッジコレクションを実装するとしたら、回収されたオブジェクトのデストラクタはどのタイミングで呼ばれるべきか?という問題提起があった。Stroustrupは、「呼ばない」という選択肢を推していた。

C++上がりのプログラマJavaに触ったとき、Javaにデストラクタがないと知って驚く人が多い。そんなときは、僕は、何のためにデストラクタが必要なのか聞くことにしている。Stroustrupさえデストラクタ不要論なのだから、まず、その議論は負けないだろう(笑)。

でもちょっと待てよ、と思った。Stroustrupの名言の一つに「リソースの取得と初期化」という原則がある。これは、外部資源(例えば、ファイルアクセスなど)の取得とオブジェクトの初期化を対応付けるという考えだ。当然、資源の解放は、デストラクタで行うということになる。この手法に基づいてプログラミングしてきた人から見ると、デストラクタが呼ばれないなんて正気の沙汰じゃないような気がしてくる。

これに関係あるかもしれないが、Javaでは、オブジェクト生成時の例外安全性がどうしても甘くなると感じている。もしも、「なんでJavaでデストラクタなんて必要なんだ?(・∀・)ニヤニヤ」なんて言う奴がいたら、この点を突破口にして論破しようと思う。