C++のこれまでとこれから | Bjarne Stroustrup講演@東大「The continuing evolution of C++」参加報告


概要

イベント情報
項目 内容
イベント名 The continuing evolution of C++
URL https://www.ci.i.u-tokyo.ac.jp/site/?Stroustrup
https://u-tokyo-ist.connpass.com/event/92085/
開催地 〒113-8656 東京都文京区本郷7-3-1
東京大学工学部2号館212号講義室
開催日時 2018-07-27T15:00 ~ 17:00
参加人数 180
SNS C++の生みの親Bjarne Stroustrup来日・講演録 – Togetter

当日の講演の様子はhttp://todai.tvで後日公開予定とのことだ。

経緯

6月半ばにこのツイートを誰かのリツイート経由で目撃したのがきっかけだった。

Bjarne Stroustrupはプログラミング言語C++の生みの親だ。C++は,Webブラウザー (Chromium),データベース (MySQL),コンパイラー (GCC),ゲームエンジン (Unity, UnrealEngine),大企業のGoogleやYahoo! JAPANなど,多数のミッションクリティカルな部分で使われており,もはやC++なしでは現在の情報社会は成り立たないといっても過言ではない。プログラミング言語の歴史に間違いなく名を残す偉大な人物だ。存命中にお顔を拝めるとは思っていなかった。

過去に氏が日本で講演したという情報がみつからなかったので,今回の来日・講演が初だったのではないだろうか。氏は1950-12-30生まれであるため,今年で68歳でありご高齢である。今回の機会を逃すと,二度とお会いできないかもしれない。

主要なLinuxディストリビューションの一つであるDebbianの創始者のIan Murdockが2015-12-28に42歳という若さで亡くなった。人の生命は儚いもので,いつ誰がいなくなってもおかしくない

C++を学ぶ者として,なにがなんでもC++を作った人を自分の目で確かめたかったので参加した。案の定,申し込み受付開始日中ですぐに埋まった。

なお,氏は何かの用事で来日していたようで,以下のツイートにもあるように,今回の東大以外にも早稲田大学やモルガン・スタンレーでも講演があったようだ。おそらくIEEEの会議があったのだろう。

感想

講演の内容はC++について大きく5点だった。

  1. 歴史
  2. 基本的な役割
  3. 最近の進化
  4. 将来
  5. 現代的コーディングスタイル

会場は人が多かったので,インターネットはつながらなかったので,SNSへの投稿や,他の人のコメントは把握できていない。

ローカルで記録した手元のメモを元に,自分の英文解釈も交えた内容を掲載しながら,コメントしていく。記憶違い,聞き間違いなどがあるので,あくまで参考程度だ。

歴史

C++の話の始まりとして,これまでの歴史や経緯などの話から始まった。

言語の価値はアプリケーションの質で決まる。DropboxやMySQLなどは世界中のみなが気にする。

これはそのとおりで,いくら優れた技術でも,使われなければ意味がない。

歴史の話

1980年代前半,ほとんどのパソコンは1 MB,1 MHz以下の性能の世界。当時はオブジェクト指向は遅く,複雑だから役に立たないと思われていた。

C++はIT技術の黎明期から開発が始まっており,これらの低スペックのマシンでの稼働も念頭におかれている。

C++の始まり

1979年にベル研のプロジェクトで始まった。

当時は,アセンブラ,BCPL,C,FortranやSimulaなどが存在していた。

Fortranは特定領域向けのDSL (Domain Specific Language)。Simulaは世界初のオブジェクト指向型の言語。

C言語にオブジェクト指向を取り入れられたような言語は当時存在しなかった。

そこで,C言語にSimulaの機能を取り入れた言語として,C++の開発が始まった。

C with class = C + Simula

C++がC with classとしてC言語とSimulaを組み合わせた言語として開発が始まったという話は,C++の本でよくでてくるが,本人の口から聞けたのは印象的だった。

基本的な役割

C++がどういう機能を持ち,役割をもっているかの説明が始まった。

C++の役割

  • エレガントで効率的なプログラム
  • Simulaのような抽象化
  • リソース制限のあるアプリケーションのため
  • 基盤ソフト

これらを実現するための機能を提供

  • ハードウェアへの直接マップ
  • 抽象化のためのゼロオーバーヘッド

全てのために完璧な言語はない

C with classを実現するために,C言語が担ってきたリソース制限のあるアプリケーションや基盤ソフトをカバーしつつ,Simulaのオブジェクト指向を組み込もうとした。

ハードウェアへの割当

基本演算子はそのまま

-, +, ->, [], ()

その他,配列やクラスは連続な作りにした

これらの作りを単純化したのが成功の一因

C++の演算子 (-, +, ->, [], ()) はハードウェアにそのまま割り当てられるようにし,さらに配列やクラスはシーケンスな構造にしたとのことで,このあたりが高速化などにもきいてきているのだろう。

ゼロオーバーヘッド抽象化

抽象化しないとよいコードをかけない。

コンパイル時計算とか。

抽象化すると理解や利用が簡単になる。

たまにC言語もC++もそんなに違いがないということをきくことがある。C++がCと違うところの一つが,この抽象化の部分だ。オブジェクト指向の概念がはいったことで,抽象的な記述か可能になり,見通しも良くなった。それだけでなく,ゼロオーバーヘッドな作りにしたので,速度も犠牲にしなくて済んだとのこと。

リソース

リソースの解放を暗黙で保証

STLは要素を管理

いくつかのライブラリーのクラスはメモリー以外のリソース (スレッドなど) も管理している

ローカルスコープでのポインターの利用は例外危険

生ポインターを使わないように

shared_ptrを使えば,delete不要。ポインターを使い終わったら勝手に解放。

もっとシンプルなのは,スコープつき変数

ユニバーサル初期化子でやる

C++98までだとリソースの管理が面倒くさくて,メモリーリークの温床だった。C++11から,このあたりがだいぶ改善されて,楽になった。

ムーブセマンティクス

オブジェクトをどう動かすか,コピー無しでスコープ外に

returnでオブジェクトを返す場合。

昔はこれはコピーだったので,コストが高かった。

今 (C++11から) はこれはポインターをそのまま渡すようになった。

これもC++98の話だ。昔は関数でオブジェクトを返すと,その都度コピーしていた。C++11からムーブセマンティクスに対応して,基本的にコピーではなくなった。

C++で一番好きな機能: } (閉じ波括弧)

閉じ波括弧でスコープが保証される

ここはちょっと驚きだった。閉じ波括弧というなんともマニアックな機能がお気に入りだとのこと。たしかに,閉じ波括弧でスコープを形成でき,これにより自動的にオブジェクトの解放もできるので,大事なのかもしれない。

オブジェクト指向

C++はただのオブジェクト指向ではない。

  • ハードウェアへの直接マップ
  • 値に意味論がある。左辺値,右辺値
  • 関数とデータの分離
  • 汎用プログラミング (汎用型,アルゴリズム,テンプレート,マクロは最初失敗)

C++のオブジェクト指向の特徴について説明していた。オブジェクト指向を単純に取り入れると,複雑になってパフォーマンスが落ちるが,ハードウェアへの直接マップや,データ構造を工夫して,パフォーマンスを維持して,うまくなっている。

最近の進化

C++の標準化の話が始まった。

標準化

  • 悪魔になるのか?
  • 単独企業に支配されてはメジャーになれない (Java, C#, Go…)
  • 多くの標準規格がある。
  • 長期的に安定化が特徴
  • ベンダーニュートラル

最初に標準化の意義について話していて,よかった。特に,単独企業に支配されてはいけないというところが,とてもよかった。

1990年頃に委員会ができて標準化をやってきた。

最近の進化。

C++98: 例外やテンプレート

C++11: C++98から10年分以上の機能追加

C++11は新しい言語みたい

C++98だとムーブセマンティクスがなかったから,関数の返却コストがきつかった。今はかなり効率的。これがとても大きい。

C++14: C++11を完全にする。

バイナリーリテラルとか,桁区切り。

標準化委員会のこれまでの成果として,C++98やC++11などで決めた機能を解説していた。C++98からC++11の変化は大きく,これによりC++が非常に強力になった。

コンパイル時計算

constexprはtype-rich,コンパイル時プログラミング

定数引数はコンパイル時に値に変換可能

concise式のアイデア

autoとラムダ

複雑さ

  • 安定性は重要な特徴の一つ
  • 言語はだんだん複雑になる
  • しかし,使い方は簡単にできる
  • 簡単なことを簡単にする

forの進化

for (int i=0; i<len; ++i)

for (auto & i : array )

for_each()

C++11で入った機能として,constexprによるコンパイル時計算やautoやlambdaによる簡単化について解説していた。C++の言語仕様はますます巨大で複雑になっていくが,コーディングには簡単なことをより簡単に実現するための構文を取り入れることで,改善していっている。新しい仕様ができて,より簡単にできる構文などはチェックしていかないといけないな。

目標

  • 型とリソース安全
  • 他よりも早く
  • 現代のハードウェアにフィットさせる
  • コンパイルも早くする

C++の今後の目標を話していた。新しいハードウェアはどんどん登場するし,新技術により他の言語も早くなっていく。それらに負けないように,C++もよりよくしていくとのこと。

哲学

  • 哲学は言語の方向を決めるのに必要
  • 言語はただの機能の寄せ集めよりも大きな塊

『C++の設計と進化』 (The Design and Evolution of C++)

「C++の設計と進化」はC++の設計についてStroustrupが書いた本だ。プログラミング言語の設計を開発者自らが解説した本として,「まつもとゆきひろ 言語のしくみ」で貴重な本だと解説されていて初めて知った。いつか読みたいと思っていたが,まだ読めていない。

将来

ここからC++の将来の話が始まった。

  • concepts
  • contracts
  • modules
  • coroutines

C++20やそれ以降の将来で標準化で盛り込むキーワードを紹介していた。

汎用プログラミング,テンプレート

1980年ではマクロで実現していた。

問題

コンパイル時ダックタイプ

テンプレートは便利で人気になった

柔軟性

パフォーマンス

メタプログラミング

コンパイル時計算

解決策: constexpr

汎用的なプログラミングを実現するために,いろいろ課題があったようで,constexprによるコンパイル時計算でいろいろ解決できたようだ。

C++20のConcepts機能

  • ソートしたいときどうするか
  • コンパイル時にpredicate

Contract

  • 特定の制約を簡単にする
  • 実行時にチェック

C++20からConceptsとContractという機能について説明していた。共にコンパイル時に関数やクラスの型に関する情報を指定する機能のようだ。

Modules

  • モジュール化、マクロから守る
  • コンパイル時間と短縮
  • includeではなくなる

以前からC++には,現在の#includeでヘッダーを取り込むのではなく,モジュールという機能でマクロを使わないモジュール化の機能が検討されていることをきいていた。C++20ではこれが入るのかもしれない。

現代的コーディングスタイル

C++のコアガイドライン

C++のコアガイドラインとして,ISO C++で公開しているものとMicrosoftで公開している2種類のガイドラインを説明していた。

こんなガイドラインがあることを知らなかったので,これはよかった。

質疑応答

講演の最後に質疑応答の時間が設けられた。会場から活発な質問が飛んだ。

全部はメモしていないが,記録に残っている部分を記載する。

Q. なぜC++11で関数がユニークになったか?

A. (回答が長く複雑だったので,失念)

C++11での変化についての質問だったが,質問も回答もよくわからなかった。

2018-08-04追記: この質問はこちらの意図だった可能性が高い。

Q. Google C++ガイドラインについてどう思う?

A. これはC言語との共存も念頭に置いていて,古いので推奨しない。isocppのガイドラインを推奨する

C++のコーディング規約はGoogle C++ガイドラインがけっこう有名だ。しかし,これももう古くなってきているので,ISO C++のガイドラインをみておけばいいようだ。

Q. deprecateはどう影響ある?

A. 影響はない。

コンパイラーのオプションで、動作させなくはできる。

C++の機能で[[deprecated]]属性というのがあるのだが,これがコード中にどういう影響があるかという質問だったと思う。基本的に影響はないらしく,コンパイラーのオプションでエラーにしたり,警告を出したり,無効にしたりできるようだ。

Q. C++は使うには難しくないか。ソフトソリューションとしてどう使うのがいいか。

A. CではなくC++。複雑な問題を解く場合によい候補になる。

JavaとかSwiftとかC#は 特定企業のもの、プラットフォームで使えるのが変わる。

msはC# しかサポートしない

C++は難易度が比較的高く,仕事もけっこう限られる。個人的にも悩んでいる。回答も,よくある無難なもので,複雑でパフォーマンスが求められるところに使うのがいいというもの。

まあ,そうなんだけど,そういう場面では,かなりのプロフェッショナルなものを求められる。しかし,もう少し簡単な仕事がないと,そこまでの専門性を身につけられない。だから,C++の仕事は一部の天才だけの仕事になってきているような感じだ。

Q. テンプレート使うときのエラーが複雑すぎる

A. 問題はコンパイル時の、ダックタイプ。

ドラフトで作業中。

C++のコンパイラーのエラーが長大で複雑だという質問。ドラフトで作業中とのことで,今後改善されるのかもしれない。

Q. Rustについてどう思う?

A. 細かいコメントは避ける。

これはTwitterで書いている人がいたので,引用。まあ,C++の生みの親だし,他の言語についてはそこまで言及しないよね。

結論

おそらくこのような機会は二度とないので,C++の生みの親を自分の目で見て,その言葉を自分できけたのがとてもよかった。

自分の英語力とC++力があまりなかったので,言葉を交わして議論できるまでいけなかったのが惜しい。しかし,同じ場に入れただけでもとてもありがたかった。

あまり,細かいところはわからないが,ISO C++のコーディングガイドラインがあることを知れたのが,実務的な部分でよかった。

今後の励みにしていきたい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です