日別アーカイブ: 2018年8月9日

C++の劇的な進化に圧倒されるModern C++

C++は、アンテナハウスでは主力のプログラミング言語です。Java, Scala, C#, JavaScript, Python, PHPなども製品、サービス、社内利用では使われていますが、多くの製品は、C++で書かれています。
C++で書かれた中核コードの古いものは、数10年経っています。
その間に、C++は、C++11, C++14, C++17とずいぶんと進化し、3年ごとに新規格にするので、もうすぐC++20になります。以下では、C++11以降のC++をModern C++と呼ぶことにします。
アンテナハウスでも、いつまでも古いC++のコードを書き続けるわけにはいかないので、昨年くらいから、Modern C++に移行するために、勉強会をしたりしています。

忘れないように先に書いておきますが、アンテナハウスでは、C++の経験者を募集中です。詳しくは、
経験者採用情報
をご覧ください。多くの方のご応募をお待ちしております。

Modern C++を勉強し始めて驚いたのは、古いC++から、あらゆる面で劇的に進化していること、そして、いまも進化を続けていることです。3年ごとに新規格にすることになったのが、着実に、そして劇的に進化した大きな要因だと思います。

Modern C++で劇的に変わった点を、思いつくままに挙げるだけでも、

  • 型推論
  • using
    もうtypedefは使わない。
  • スコープ付き列挙型(scoped enum)
  • 各種スマートポインタ
    もう生のポインタを使うのは、Cのレガシーコードとインターフェースするときのみ。
  • 右辺値、右辺値参照、ムーブセマンティクス、ムーブコンストラクタ、ムーブ代入演算子
    Modern C++以前は、あいまいだった所有権や一時オブジェクトの扱いを明確化したことで、ムーブによって無駄なコピーを減らして、高速なコードが書けるようになった。
  • ラムダ式(クロージャ)
    プログラミング言語としては、Lispが50年前に導入したものが、ようやく入った。
  • テンプレートプログラミングの劇的な強化
    constexprによるコンパイル時計算の強化。コンパイル時にいろいろ調べられるメタプログラミング機能、SFINAEをやりやすくする機能の強化。
    SFINAE
  • 上記に伴う標準テンプレートライブラリSTLの変更

などなど、たくさんあります。

C++とプログラミングパラダイムの関係を考えると、C++は、

  • Cの命令型プログラミング(手続き型プログラミング)に、オブジェクト指向プログラミングを追加
  • GenericsとTemplateによる汎用テンプレートプログラミング

といったマルチパラダイム言語に進化してきました。
Modern C++は、汎用テンプレートプログラミングというパラダイムをさらに推し進め、テンプレートメタプログラミング(TMP, Template Meta Programming)を強化し、流行りの関数型プログラミングの強化も抜かりなくやっていて、マルチパラダイム言語としてますます強力になった印象です。

古いC++では、テンプレートメタプログラミングは、そのエキスパートしか書けない黒魔術の世界でした。それが、中級のスキルがあるC++プログラマなら書ける程度には楽になりました。
しかも、ネイティブコンパイルですから、実行スピードは、RubyやPythonといったスクリプト言語に比べ桁違いに速く、JavaやScalaと比べても速い。
スマートポインタを使えば、以前のようなメモリの管理の面倒もなくなり、ガベージコレクションがあるJava, Scalaやスクリプト言語のように楽に書けます。
さらにいえば、型推論と関数型プログラミングの強化によって、個人的には、Scalaのようになってきた印象があります。
型推論のおかげで、テンプレートプログラミングが非常に楽になりました。型推論がないテンプレートプログラミングは、プログラマにとって地獄ですからね。

とまあ、いいことづくめのModern C++ですが、既存のコードをModern C++に全部書き変えるのは、事実上不可能なので、新しく書くコードをModern C++で書こうとしています。
しかし、ここで商用ソフトならではの問題があって、お客様の中には、古いC++でシステムを構築していて、ランタイムライブラリの関係で、容易には、Modern C++の環境に切り替えるのが困難なお客様がいらっしゃいます。
たとえば、Visual C++ 2005(!)どころか、Visual C++ 6.0(!!)の環境でシステムが動いているところがあるのです。
もう1つの問題は、マイクロソフトのC++は、GCCやClangに比べ、現時点では、規格の準拠度がまだまだで、Modern C++の機能を駆使したコードが正しくコンパイルできないといった問題もあります。

ということがあるので、移行はゆるやかにやっていくと思いますが、Modern C++を使うことで、速くクリーンで、拡張性、保守性もいいコードにして、お客様に少しでも早く、いい製品をお届けしたいと思っています。

最後になりますが、ご参考までに。
Modern C++の規格やライブラリの解説は、次が非常によいです。
cpprefjp – C++日本語リファレンス
たとえば、
言語機能
を読めば、C++11, C++14, C++17, C++20と、何がどれくらい変わっているかがわかります。
また、次も非常に参考になります。
C++リファレンス