筆者のC++エピソード
最後になりますが、筆者とC++とのお付き合いを紹介して本稿を締めたいと思います。筆者は、30年ほど前はC/C++のプログラマをやっていました。恥を忍んで年齢を明かすと、ほぼアラカンです。つまり、30歳前後という、プログラマとして脂が乗りまくっている時期にC++をたしなんでいました。当然、C言語歴も長く、C言語にオブジェクト指向プログラミングのパラダイムを持ち込んだC++は必然の選択でした。
PC-9801+MS-DOS全盛の時代
貴重なミニコンやワークステーションが使える大学や企業を除けば、NECのパソコンPC-9801とMS-DOSで動くアプリケーションを作る、というのがコンシューマレベルの趨勢でした。当時人気のあった日本語ワープロの「一太郎」や表計算ソフトの「Lotus 1-2-3」などは、この組み合わせで動くように開発され、個人・法人を問わずに多くの場所で使われていたのです。
あくまでも想像の域を出ないのですが、これらのアプリケーションは主にC言語によって開発されていたに違いありません。MS-DOSというメモリ制約の厳しいOSと、あまり速くもないCPUと貧弱なファームウェアを積んだパソコンでは、「高級アセンブラ」と揶揄されるC言語が、もっともアプリケーション開発に適していたことは間違いないからです。
筆者も1980年代から長い間、このC言語を用いて(部分的にはアセンブリ言語を用いて)アプリケーションを開発していました。国内におけるC言語草分け期のLattice C、Optimizing Cから、徐々に標準になりつつあったMicrosoft C Compilerをバージョン7まで使い続けたのです。
ウインドウシステムの登場
1990年ごろからWindowsやOS/2といったウインドウ環境が登場し、それらに対応するアプリケーションの開発も視野に入れる必要が出てきました。Microsoft Cのバージョン7にはMFC(Microsoft Foundation Class)という今でいうフレームワークが搭載され、C++によるウインドウアプリケーションの開発に対応していました。このバージョンは、まだまだコマンドラインツールによる開発がメインだったのですが、その後に登場するVisual C++ 1.0によって、GUIによるアプリケーション開発がはじめて可能になるのです。
そこで筆者は、プラットフォームの過渡期(Windowsはまだまだ本格的なアプリケーションの稼働には難がありました)であることを踏まえて、MS-DOS用とWindows用のアプリケーションのソースコードを共通化することを思いついたのです。WindowsではMFCをベースにした開発を行えばよいだろうということで、MS-DOS向けのソースコードをMFCに準拠させる形で書き直すことを始めたのです。
MFCはC++で記述されているので、MS-DOS用に書いた多くのライブラリをC++化することにしました。こうして筆者による、MS-DOSのアプリケーションをC++で書いていくという無駄、いや無謀なチャレンジが始まったのです。
RADツールの登場とともに疎遠になるC++
1990年代中盤になるとWindows 95が登場し、ウインドウシステムとしても実用的になって多くのアプリケーションが登場します。開発環境も充実し、いわゆるRAD(Rapid Application Development)ツールが多く見られるようになってきました。Visual C++ 4.0、Visual Basic 4.0、そしてDelphi 2.0などです。全て、WindowsアプリケーションをGUIで開発できるのですが、コンポーネント指向のVisual BasicとDelphiは絶大な人気を博しました。
Delphiは、Object Pascalという当時としては最新鋭のオブジェクト指向のためのプログラミング言語を備え、Windowsアプリケーション開発との相性が素晴らしく、筆者はさっさとメインの開発プラットフォームをDelphiに移してしまいました(Delphiとの付き合いは長く、今に及んでも開発のお世話になっています)。ひどいことに、Javaをはじめとする本格的なオブジェクト指向プログラミング言語が多数登場する中で、C++の存在はすっかり忘れていました。いえ、忘れていたのではなく、何を今さらC++ということで、他の多くの魅力的なプログラミング言語が存在する中で、あえて彼を使うという発想がなかったのです。
RustとModern C++によって目が醒める
そうです。もうお気付きでしょうが、筆者のC++についての認識も知識も、1990年代前半頃で止まっているのです。その後は、プラットフォームとしてはとりあえずWindowsを意識しておけばいいので、あえてC++の世界に戻る必要もなかったのです。筆者の中のC++は、あくまでもC言語にオブジェクト指向プログラミングのパラダイムと言語仕様を持ってきたもので、シビアなメモリ管理は相変わらずで使いにくいものなのです。
しかし、RustやKotlin、Swiftといった設計の新しいプログラミング言語に触れるにつれ、これらが新しい意味論(セマンティクス)に基づき設計され、それにはC++の影響が小さくないことに気付きます。そうです、C++は新しい言語にも影響を与えるほどの変貌をいつの間にか遂げていたのです。例えばRustは、C++ 11で仕様に組み込まれたライフタイム(寿命)やムーブセマンティクス(移譲)、スマートポインタの概念を取り入れて改良したということがあります。また、2010年代にリリースされたSwiftやKotlin、改良版のJavaなどでは型推論が当たり前のように実装されています。これらを探るうちに、Modern C++という新しいムーブメントの存在にようやく気付くのです。もちろん、すべてがC++発祥というわけではないでしょうが、静的型付け言語の中でC++の与える影響は小さいものではないはずです。
まったく以て、これは筆者の怠慢だったことを恥じるほかありません。面倒くさい言語というのはまったくの偏見であり、濡れ衣だったのです。ゴメンネ、C++。
まとめ
今回は、Modern C++の世界に入っていく準備として、かつてのC++の常道をおさらいし、筆者のC++との付き合いをお伝えしました。本連載は、要は30年前の古い認識と知識しかC++に対して持っていない筆者が、21世紀のC++の言語仕様を探訪するというものです。同じような境遇のロートルプログラマの方々はもちろん、これからC++をやってみようかなというニューカマーの皆さんにもお楽しみいただけたらと思います。
次回からは、いよいよModern C++の「ここが新しい」をお伝えしていきます。まずは、「データ型を明示しないで!」で触れたautoによる型推論です。