March 22, 2011
C++創造者Bjarne Stroustrupへのインタヴュー

source: An Interview with C++ Creator Bjarne Stroustrup - CodeGuru

C++0x標準化作業がまもなく最終投票段階になるいま、C++の創造者たるBjarne Stroustrup博士とサシでC++0xの新しい機能と将来について語る機会を得た。

  • DK: Danny Kalev
  • BS: Bjarne Stroustrup

Table of Contents

1 Page1

  • DK C++0xの標準化作業はどのあたりまできていますか?いつぐらいに国際標準となる見込みでしょうか?
  • BS 最終投票は2011/3/26を予定しておる。見たところ不安要素はないな。その後、正式な国際投票や、ISOのお役所仕事で遅れるにせよ、2011年中には公式な標準として成立するものと確信しておる。
  • DK 言語coreやライブラリの拡張の面で、普通のC++erがC++0xによって享受できるメリットはありますか?C++0xであなたが特にこれは素晴しいと思うものは?そして、C++0xに関する書籍がまだ少ない事を踏まえた上で、C++0xの新機能を習得するお勧めの方法を教えてください。
  • BS C++の進化は特定の”目を引くような”機能によるものではなく、小さな積み重ねを続けた結果によるものだ。とてもマイナーには見えない改善もあるがね。 なんにせよ、それらはわしの”C++0xの改善は偏在的であるべき”という要点から外れるものではない。 つまりだ、特定の問題領域の特定部分でしか使えぬようなものではなく、あまねく種類のあまねくコードで役立つような改善になっておる。 そうだな、言いかえれば、「わしの”大工道具”にすてきな”レンガ”がたくさん増えて、いままで一筋縄では建てられなかったものが綺麗に建てやすくなった」感じかの。 実際、C++0xで書くよりC++98で書いたほうがエレガントかつ高速になるプログラムは…ちょっと思いつかんの。 それではC++erの人生を少々楽にするちょっとした変更を見てもらおうかの。
    void f(vector<pair<string,int>>& vp) 
    {
            struct is_key {
                    string s;
                    bool operator()(const pair<string,int>&p)
                    { return p.first == s; }
            };
            auto p = find_if(vp.begin(), vp.end(), is_key{"simple"});
            // …
    }
    

    なんの変わり映えもないように見えるかのう。しかしこのコードにはC++98では出来なかった4つのちょっとした変更があるのだ。順に見てみよう。

    1. vector<pair<string,int»の>と>の間にスペースがない。これはわしが思うにC++0xの変更のなかでも最も小さいものだが、これでプログラマーは“不要な”スペースを書く必要がなくなる。
    2. pの実際の型を書かず、autoを使って宣言している。これは”initializerの型をそのまま使え”という意味で、pはvector<pair<string,int»::iteratorだ。これでタイプする量がちょっと減り、よくあるバグを減らすことができる。autoはわしが1983年に実装した最初のC++0x機能だが、そのときはCとの互換性を保つために消さざるをえなかった。
    3. local structのis_keyがテンプレート引数型を取っている。気づかなかったかも知れぬが、これはC++98ではできなかった。
    4. 最後に、わしはinitializer{“simple”}を使ってkeyを構築したが、これはC++98では変数だけにしか許されない初期化で、関数の引数には使えなかった。C++0xには{…}を用いたuniform/universal initializationがある。
    lambda expressionを使えば先の例はもっとシンプルになるぞ。
    void f(vector<pair<string,int>>& vp) 
    {
            auto p = find_if(vp.begin(), vp.end(),
            []()(const pair<string,int>&p) { return p.first=="simple"; });
            // …
    }
    

    lambdaは関数オブジェクトの定義と呼び出しを簡略化するものだ。見るがよい。find_if()の述語関数はpairの引数を取って、そのfirst-elementと”simple”を比較する、ということが簡潔に表現されておる。

    さて、ここまででマイナーな改善がすばらしい事は分っていただけたかの?ではメジャーなものも見ていこう。

    • system-levelの並行処理でよく使われるthread-and-lockスタイルの直接かつtype-safeなサポート。detailed memory modelとlock-free proggrammingの機能と組み合わせることで、ポータブルかつ効率的な並行処理のサポートを提供する
    • futureと呼ばれるメッセージバッファを用いた非同期”タスク”通信をベースとする、より高次の並行処理モデル
    • 標準ライブラリに正規表現が組み込まれた
    • ハッシュコンテナ
    • move semanticsと、標準ライブラリのmove semantics対応。これについては特に言っておかねばならんが、関数から巨大なオブジェクトを値返しすることができるようになったのだ。こんな風にの。
      vector<int> make_vec(int n)
      {
          vector<int> res;
          for (int i=0; i<n; ++i) res[i] = rand_int(0,100000);
          return res;
      }
      

      標準ライブラリのvectorには、全ての要素をコピーするのではなく、単にvectorの実体を受け渡す”move constructor”がある。 これで、かつてC++03でコピー処理に莫大な回数のメモリ割り当てが必要だったreturn処理が、たった6回程度でできるようになる。もうポインタや参照を使ったり、フリーストアをこねくりまわすような小賢しい事をしなくてよくなったのだ。 move semanticsは巨大なオブジェクトの受け渡しで効果を発揮するまったく新しいパラダイムだ。特に、効率が重視される値生成操作の実装や利用が簡単になる。次のmatrixのadd関数などいい例だろう。

      Matrix operator*(const Matrix&, const Matrix&);
      
    まだまだ言う事はあるが、長話は退屈なだけだの。先に進むとしよう。次の質問は面白いのぅ。「これらを全て使いこなすにはどう学んだらいいか」。現在わしはThe C++ Programming Languageの第四版の執筆にかかっておるが、まだまだやる事が残っているのであと一年くらいはかかるだろう。 わし以外にももう書き始めていたり、書こうと思っている方がおる事は間違いないが、初心者からエキスパートまでサポートする教材や本が出揃うにはまだ時間がかかるだろう。 幸いな事に、並行処理についてはもう素晴しい書籍が発行されておる。Anthony Williamsの C++ Concurrency in Action - Practical Multithreadingだ。 またわしのC++0x FAQも参考になるだろう。このFAQにはC++0x機能や標準ライブラリ機能を使った短いサンプルがあり、現在利用できるもののリファレンスとしても使える。 だが、本当必要なのはFAQsやonline document以上のもので、新しい機能をどう使ってより良いプログラミングをするかについて一貫した説明がされたものだ。そう、教科書だ。

    わしがProgramming: Principles and Practice using C++を執筆したときには、もうC++0x策定の仕事にとりかかっていたので、C++0x機能なしで執筆するという縛りはキツかったのう。 わしは教育や学習の面でもC++0xによる恩恵があるとみておる。プログラミングテクニックやスタイルのサポートが更に良くなったからだ。例えば、C++0xにはuniform/universal initializationというメカニズムがある。 これで、どんな初期化であっても{…}と書けばいいので、Xを初期化するには{v}と記述しさえすれば良くなる。 これは =v ={v} (v)といった初期化を使い分けなければならなかったC++98のnon-uniform に比べて飛躍的な進歩だ。

    vector<double> v = { 1,2,3,4};  // a user-defined type
    double a[] = { 1,2,3,4};                // an aggregate
    int f(const vector<double>&);
    int x = f({1,2,3,4});
    auto p = new vector<double>{1,2,3,4};
    struct S { double a, b; };
    S s1{1,2};                      // has no constructor
    complex<double> z { 1,2,};      // has constructor
    

    C++0xがもたらす簡素化という利益をうける前に、自慢気に言語仕様をずらずら並べられたり、言語仕様の隅をつつくような話をうだうだ聞かねばならぬとしたら、それは害以外のなにものでもない。

    わしらはただ読むだけでC++0xプログラミングをよく理解できるとは思っておらん。実際に新しい機能を使ってみねばなるまい。となると、現時点でC++0xの機能とライブラリ機能が数多く搭載された実装(たとえばGCCやMicrosoft)があるのはすばらしいことだ。 C++0xは今や現実のものとなっておる!

  • DK C++0x標準化は当初の予定より3年遅れています。Perl6Java SE 7のリリースもかなり遅れているようです。今日の標準化作業は以前よりも長い時間がかかるようになったように見受けられます。 これは21世紀のプログラミング言語固有のなにかがあるのでしょうか?標準化作業自体の問題でしょうか?それともいつもの事なのでしょうか?
  • BS 以前より、言語自身はもちろんの事、付帯するライブラリはそれにも増して肥大化した。大量の過去のコードを破壊せぬよう保たねばならん。 その上で、複雑さに対処するコスト/時間はサイズに比べて線型にはならぬ…おそらくは少なくとも二乗のオーダーになるだろう。 というのも、標準ライブラリの機能と言語の間でありうる全ての相互作用を検証せねばならんからだ。

    標準化プロセスの本質的な変化も考慮せねばなるまい。その上、オンライン・コミュニケーションの発達により、多種多様な人が議論に参加できるようになった。 二十年前は、参加できる者はごく限られておった。大企業や大学の援助があり、かつ、会議の準備に何ヶ月も掛けられ、数週間にわたる会議に参加できるような者に、の。 わしの推測ではC++98の仕様策定に積極的に参加した者は100名から200名くらいだと思うが、C++0xの仕様策定にはおおよそその4倍ほどの人間が関わっておる。 ヒューマンリソースが多いのは大歓迎だし、問題点を洗い出すには多くの人手が必要だ。 だが、一般に何かを革新するより保守に回るほうがたやすいものだ。大きなグループになると何かを革新するために必要な信頼関係を構築するのがより困難になる。ましてや種々雑多な目的やバックグラウンドを持つ者が集まるならなおさら、況んやネットワーク越しともなればことさらだ。 また、言語全体とコミュニティ全体を俯瞰できる人間が少なくなる。…というのは、小さなサブセットだけ見るほうが容易であるし、コミュニティの懸念を関係がないものとして無視したり、または”単に間違っている”として却下してしまう危険性がある。

    これら二つの効果により、コミュニティはますます保守的になってしまう。 わしはコミュニティが行なった事にも、成し遂げた事にも驚いておる。 コミュニティの中の技術的かつ思想的な障害を乗り越えて着想(vision と言い替えてもよい)を得るのは耐えがたいほど遅々として進まず、困難なことがある。 特に、FUD(訳注:Fear, Uncertainty and Doubt「恐怖、不安、疑念」)は強力な障害となりうる。 というのは、実際に使ってみるまで新しい機能がもたらす利益を見積るのはほとんど不可能なのに対し、潜在的かつ深刻な問題を推測するのは容易だからだ。

2 Page2

  • DK あなたはテキサスのA&M 大学で何年も教鞭を執ってらっしゃいます。 コンピュータ・サイエンス科の若い学生との会話のなかから、プログラミング言語のデザインに関して何か新しい着想が得られましたか?
  • BS 思っていた程ではないの。学生は普通プログラミングやプログラミング言語に関して浅い知見しか持っておらぬ。 大学生や院生に最新のテクニックや問題について理解させるのは非常に骨が折れる仕事だ。 また、大学の研究は実用的なシステム構築が主流で、言語の研究はあまり流行っておらん。 わしが大学でやらねばならぬ仕事は、様々なバックグラウンドにおけるプログラミング初心者を減らすことと、プログラミングの必要性について正しい認識を持つ者を育てる事だと思っておる。 プログラミングを始める前から必要な事を全て学ばせる事などできぬであろう。かわりに、自発的に学び始めるまでサポートするべきだ。 妥当な期間(数週間から数ヶ月、数年では長すぎるの)で習得できる”sub-language”では、1970年代や1980年代のプログラミング観に囚われた教育をしない事が肝要だ。

    教育者としてのわしの回答としては、わしの書籍 Programming: Principles and Practice using C++ がその一例かの。数年にわたって数千人もの学生を教育してきたわしや同僚の経験からこの本は生まれたのだ。 この本はC++の汎用的な教本というより、実際の、実践的なプログラミングについて紹介するものだと思っておる。 プログラミングは基礎的な理論と実践的な技術を必要とする高度な技術だーと教えるのとともに、低レヴェルの実践的スキルだけでも、理論的な枠組みだけでもないと教えるべきだ。

  • DK conceptの厄介な問題に戻りましょう。以前のinterviewで、標準からconseptを外すこと(2009/7)は”大きな取り引き”だとおっしゃいました。 別のテンプレート型制約機構(type-constraining mechanism)の研究はまだ続行されていますか? 今なら、今日とはまた違ったconceptを設計できたと思いますか?
  • BS ああ。わしはtemplateの必要条件を厳格に定義する方法を探し続けておる。 もしこれが達成されればC++ の偉大なる進化のなかでも特筆すべきものになると考えておる。 しかしだ。いかなる”concept”も産業規模で利用できなければならぬ。 conceptはプログラミング言語のスペシャリストのためだけでなく、多くのプログラマが使いやすいものでなくてはならぬ。 またruntimeやcompile-time(巨大かつ分割コンパイルされたプログラムにおいても)にオーバーヘッドがかかるものであってはならぬ。 そして、古いスタイルと新しいスタイルのテンプレートが混在したプログラムにおいても、使いやすく十分な互換性を確保せねばならぬ。 わしらがC++0xで設計したデザインは、これらの基準を十分満たすものではなかった。 また、今のところ、わしが知っている他の(研究的、実用的)言語においてもそのような仕組みはない。 …うむ。確かにわしには腹案がある。が、先に述べた基準を満たすにはほど遠い。まだまだ仕事は山積みだ。 基礎的なものから、概念的なもの、研究レヴェルのものまでさまざまだ。研究せねばならぬ事のなかには、コンパイルモデルやユーザーインターフェース(訳注:expression modelの事か)を詰めていく作業がある。 わしらがC++0xでやろうとしたような微調整ではどうにもならぬ。
  • DK 続いて、rvalue referenceについてお願いします。C++0xにおけるこのvalue systemには今、prvalue xvalue glvalueなどがあります。 加えて、C++0xには新規のオーバーロード解決規約、template推論規約、新しいcastの規約、move constructorとmove assignment operatorという新規メンバ関数、そして副作用については後で伺いますがnoexceptがあります。 もしかしてrvalue referenceは手に負えないほど広まりすぎたのではないですか? ワーキングドラフトに初めてrvalue referenceが加えられたとき、こうなる事は予見できたでしょうか?
  • BS 改善点の実装すべてについて見越すのは難しく、標準を子細にわたって見るのは困難だ。 仮に君が広く浸透した機能についてすべての詳細を纏めたとしても、他人の驚きや恐怖による反発は免れまい。 これは実際に使われている言語(non-toy language)ならば当然の事だ。 実際に実装する者の要求に応える仕様というのは信じられないほど細かく複雑なものだ。 唯一の実装しかない言語は単純になるだろう。なぜなら、人は全ての詳細を見はしないし、実装が想定している正確な概略にも興味がないー実装そのものが何をするかを簡単に教えてくれるからだ。

    わしの率直な感想を言えば、rvalue refereneceを広めたのは意図しての事だ。なぜなら、move semanticsは広く一般に使われるべきものだからだ。 わしはmove semanticsをそれほど問題なく説明できる。 rvalue referenceのもう一つの使い途であるperfect argument forwardingを説明するのは少々骨が折れる。これはそれ自身がとっつきにくいtemplate metaprogrammingを例に取らねばならんからだ。 rvalue referenceによるperfect forwardingは事実、template metaprogrammingを容易にするが、もう既にtemplate metaprogrammingに見切りをつけてしまった人には全く意味がない。

    全ての詳細について正確に定義し、他の言語機能と標準ライブラリ間で起こりうる全ての相互作用を明記するのは非常に困難だ。 これをやりきるために、わしらは新しい用語を発明せねばならなんだが、これはごく少数の限られたプログラマだけが知り、憂慮すればよい事だとわしは思っておる。 Christopher StracheyがかつてC++の祖先たるCPLを記述する際に”lvalue” と “rvalue” という言葉を発明した時、多くの人が頭を横に振った。手に負えぬほどプログラミング言語がややこしくなったせいで英語をいじくる必要が生じたと思ったからだ。

    わしはnoexceptはrvalue referenceとは別の議題だと思う。noexceptは失敗に終った例外仕様のより簡便かつ実行可能な代替手段を提供するものだと思うからだ。

  • DK それでは、全体的に見て、あなたはrvalue referenceはC++0xの価値ある一歩だとお考えですか? この機能によって、普通のC++erが性能向上以外に受ける恩恵はなんでしょう。たとえば、デザインがより綺麗になるとか、アルゴリズムがよりシンプルになるとか。 ーあるいは、この機能は主にライブラリアンやコンパイラ作者がターゲットなのでしょうか?
  • BS rvalue referenceは非常に価値があるものだとわしは思う。例えば、move semantics -これはrvalue referenceの主な使い途の一つだが- これによって長らく懸案事項だった問題に一つケリがつく。 すなわち、関数から巨大なデータを返却するにはどうすればいいか、という問題だ。move semanticsによって導かれる”単純かつ明瞭で効果的な”答えは、単に関数から返すときにムブればよい、となる。 結果をコピーせずともよい。変にメモリをこねくりまわさずともよい。こ汚ない特殊な用途に特化したメモリ管理の仕組みを使わずともよい。 呼び出し元がメモリを確保することなどいらぬ。”余計な引数”でもって渡される値もいらぬ。ガベコレなどいらぬ。 これは全てのC++erを幸福に導くのだ。move semanticsは小賢しい小手先のテクニックが必要だったことをシンプルにやっつけてくれる。

    ムブるのはとても簡単だという例を示そう。ロケット工学ではないという事を見せねばな。

    class Matrix {
        double* elem;     // pointer to elements
        int dim1, dim2;
    public:
        Matrix(Matrix&& a)
                  :dim1(a.dim1), dim2(a.dim2), elem(a.elem)
            { a.dim1=0; a.dim2=0; a.elem=nullptr; }
        // ….
    };
    

    これだけだ。値はムブられ、空のMatrixが残る。これで、10000x10000のMatrixを効率良く容易に返すことができる。

    もちろん、ライブラリアンにも嬉しい事があるぞ。つまり、ライブラリをシンプルに実装しようとするとムブる機会が多々出てくるだろうし、forwarding(もう一つのrvalue referenceの使い途だ)がライブラリのデザインや実装を助けてくれる機会も多々あるかもしれん。 だが、move semanticsとperfect forwardingは”エキスパート御用達”の秘伝のテクではないのだ。

  • DK rvalue referenceは2002年に初めて提案されましたが、FCDにはまだムブられるオブジェクトの状態(state of a moved-from object)(これは、コンパイラがmove constructorを生成する際や、アルゴリズムの最適化に必要である)といった、move sematicの基本的な解釈に欠けているように見受けられます。 ムブられるオブジェクトの状態についての争点は何処ですか?また、合意にどれくらいかかると見ていますか?
  • BS 投票結果を見れば、2010/11のpost-Fermilab-meetingで合意に逹したとわしは見ておる。 わしらは活発に議論を交したが、すべての主要な問題に決着をみた。 ムブられるオブジェクトの状態についても決着した。デフォルトでは、メンバのmove次第だ。 つまり、もしユーザー定義のmoveがある時、ムブられるオブジェクトは(例外を投げようとしたときと同じ状態、同じ理由で)有効だが未定義の状態のままだ。 constructorとassignmentの生成の規則はできるだけ違和感を覚えずに済むよう厳しくなった。

    “合意”とは多数決の結果であり全会一致ではない。 別の方法が望ましいと考える者はかならずおるだろうし、その方がより制限が緩いと言うこともあろう。(特に問題が収束する前の白熱した議論が交わされる時には) だが、わしは全員ではないにせよ殆どの委員会メンバと標準化に関わる人が、現在のドラフトが他の代案よりもよいと納得できるところに収束すると考えておる。 分別ある人間は要求が全部通るなどとは思っておらん。わしですら殆んど蹴られるからの。 いずれにせよ、大切な事は、C++0xはC++98よりもソフトウェアを開発するツールとして遥かに優れたものだということだ。

3 Page3

  • DK 数年前、あなたはパフォーマンス改善のためにSCARY iteratornoexceptimplicitly-defined constructorといった機能を提案しました。 これに対し、C++0xの標準化作業が伸びる、コードの安全性が失なわれかねない、といった理由で、委員会のメンバーからは反対の声もあがりました。 今日においてもパフォーマンスはそんなに重要なものでしょうか? 十分にテストされていない機能を採択することで委員会はどれほどのリスクを負うのでしょうか。
  • BS 確かに、C++ではパフォーマンスは大切だ。 C++はパフォーマンスが本当に問題となるようなところでは本当によく使われておる。 パフォーマンス(と同様に柔軟性)があるからこそ、ハイエンドシステム(GoogleやAmazonやAmadeus)においても、組み込み(携帯電話や車や航空機)においても、ブラウザや仮想マシン(Chrome, V8, Havok, Hotspot)でも、C++はこれほどに広く利用されているのだ。

    新しいものには何にでも反対する構図がここでも見られるの。 安全性が失われる事への恐怖はその一端だが、わしはこの提案によってC++になんら安全性に悪影響を及ぼすことがないと見ておる。 君が言及した機能で言えば、SCARYは安全性に与える影響が全くない。これは、over-constrained nested types(過剰な制約を受けた入れ子の型)でやるよりもオーバーヘッドが少なくなる、という単なるアルゴリズム実装テクニックだ。 標準コンテナのイテレータを実装する方法は主に二通りあるが、実際、これはそのうちの一つで、この提案はより効率的でより柔軟なほうで実装するように求めただけなのだ。 この場合でさえも、委員会は実装者がどちらで実装するかを制限すべきではないという声が大きかったので、SCARYは蹴られてしまった。 だがわしはこのデータを見れば、早い段階で全ての標準ライブラリ実装がSCARYをサポートすることになるだろうと見ておる。

    noexceptはどちらかと言えば(例外仕様を使ったり、手前味噌なエラーハンドリング手法を使うなどの)C++98の安全かつ高速な代替を提供するものだ。

    「委員会はどれくらいのリスクを負うのか」とはまた…「委員会はどんな危険を冒すべきですか」と同程度に難問だな。 新しい機能追加には常に危険性がつきまとう。既存のコードを破壊する危険性、混乱する危険性、製品の必要性がなくなる事で企業が損害を受ける可能性、使ってきたツールが使えなくなる危険性、教材が無効になる危険性などがあるの。 変更をしない事が100%安全なように思えるかもしれんが、ユーザーコミュニティが活力を失い、新規のプログラミングテクニックがサポートされなくなることで、結局、巨額のコストをかけて、莫大なコード修正をしなければならなくなるだろう。 危険を冒すことなく何かを成す事はできぬ。 何もせねば中期的には失敗に終わってしまうだろう。ゆえに、危険性を最小限に抑えるためには、危険をよく見積った上であえて危険を犯さねばならぬ。わしの持論だがの。

    わしはどんなに重要な機能であれ完全にはテストできると思っておらん。多数のさまざまなコミュニティの力を借りて数年間かけてテストしたとしても、だ。 また、このような「大実験」はコミュニティ全体に方言を押しつけるか、閉鎖的な環境を作ってしまうことにつながりやすい。 より小さな実験を行ない、別の方法についても考察し、よく議論を交わし、標準化に向かうべきだ。

    わしはリスクについての過剰な議論は見当違いだと思う。 ユーザーは古いコードや古い手法が使えなくなる事が最大の関心事だ。 概して、より大きな危険は貧弱な設計にある。 新しい機能が十分汎用的で、教えやすく学びやすく使いやすいことを保証するのは非常に困難だ。 新しいものに怯えていては、シンタックスやセマンティクスがひどく冗長になってしまい、言語拡張がままならならなくなってしまう。 わしらはデザインについてさらに議論し、さらにはユースケースを深く調査するほうが良いと思うのだが…、実装テクニックや技術的な詳細について議論するほうにハマってしまう者が多いようだの。

  • DK あえて冒す危険のはなしについてもう少しお願いします。(class member initializerのような)他の機能とほとんど相互作用しない独立した機能は、C++のほぼ全体に関わるような広く行きわたった機能とは対照的に、別の標準化プロセスを設けるべきでしょうか? 前者は、もし失敗したら(exported templateのように)容易に切れる一方、小さな変更でもライブラリや言語全体に影響が及ぶので後者はそう融通が効かないように思えます。 または、そんな分割を想定するのは無理だというほどナイーブなものですか?
  • BS リスクをつきとめるのは難しい。 危険だと思うものと、危険に対する寛容性は人によってまちまちだからだ。

    機能を”局所的”か”汎用的”かで線引きするのはたやすいことではない。 言語のあらゆる基本的な機能とcleanlyな相互作用をする機能となるのが理想だ。 多くの場合、代替手段は機能性の複製だ。 理想的には、名前探索の概念も、式の概念も、スコープの概念も、初期化の概念も一つだけに絞られるのがよい。 こうなれば、他の言語機能に潜在的に影響を与えず変更を行なえる小さな言語となったと言えるだろう。

    これは標準ライブラリについても言える。理想的には標準コンテナは他の標準ライブラリコンポーネントで、データを保持するために使われるべきだし、標準アルゴリズムは他のライブラリコンポーネントの実装に使われるべきだ。 別のコンテナライブラリが使われたり、データ処理にフリーストアを直接いじったり生ポインタを操作したりするようであれば、それは失敗作だ。

    わしの結論を言えば、言語や標準ライブラリのリスクを抑えるには、言語機能や標準ライブラリにリスクを積み上げないようにすることでしか達成できない。 しかし、標準化プロセスを分けてしまうと、標準の模写/冗長性はいやおうなしに増大し、規格のサイズはひどく増え、実装と学習にかかる時間はむだに増加してしまうだろう。 また、標準化プロセス毎に異なった用語が使用されてしまうと、規格にしこりができてしまい、結果、標準の異なった部分を疎結合することはまったく不可能になってしまう。 特に、標準委員会は、(狭いコミュニティで使われているただのサブセットよりも)言語全体に関心があり、言語全体を(適当な深さで)理解している人材をもっと多く必要としている。

  • DK FCDにあるnoexceptについてお聞かせください。 関数が例外を投げない事を示すthrow()という仕様がもうあるのに、どうしてnoexeptが必要なのか、という点にC++erは引っ掛かりを感じると思います。(例外仕様がダメダメな事はひとまず忘れましょう) throw()よりもnoexceptのどこが優れているのでしょうか。 noexceptの静的なチェックが限られている事を考慮すると、これは新しいセキュリティリスクをもたらす事になりませんか?
  • BS いや、noexceptは安全性に穴を空けない。というより、throw()に比べれば少しはマシになる。

    CERTは委員会が認めたnoexceptをサポートしている 例外の送出を静的に検出したい、と言う者もいるが、わしはその一員ではない。大規模システムで使えて、効率的で、容易にバイパスできない静的チェック機構を持つ言語はいまだない。 C++98の例外仕様はないよりましという妥協の結果だった。

    C++98の例外仕様は0xではdeprecatedとなった。もはや使ってはならぬ。 というのは効率に問題があり、思わぬ落し穴があるからだ。 noexceptは、例外仕様がうまく機能したたった一つの例、すなわち関数が単に例外を投げない事を示すことに対応する C++98では、throw()をつければよいという者もいたが、その方法では著しいオーバーヘッドがあるかもしれないし(そういう実装もある)、結局、(潜在的に未知の)unexpected handlerを実行することになるかもしれない。 noexceptつきなら例外送出は致命的なデザインエラーであり、プログラムはただちに停止される。 これによって、安全性の向上と大きな最適化向上につながるのだ。

    noexceptが利用されるようになれば、例外を使う責務がより重くなり、より安全なコードを書くことに繋がるのだ。

  • DK rvalue referenceやlamda expression、それにもちろんconceptといったC++0xの機能をデザインするのにまつわる苦労は、C++が古すぎて拡張性がないという批判につながります。 この批判にも一抹の真実はありますか? C++にはもはや拡張、改良の余地はなく、代りになる新しいプログラミング言語が必要だとされる時は来るのでしょうか?
  • BS わしがよく聞くのはC++はあまりに拡張性がありすぎることと、あまりにも大きすぎるというクレームだな。 新しいプログラミング言語はまだバックに巨大なコミュニティがいないためかシンプルになるようだの。 いかなる言語も時間をかけて育っていく。 もちろん、大きく、歴史があり、広く使われている言語は、新しい言語に比べて変更が容易ではない。 しかしながら、殆どの言語は未成熟のまま死んでいく。そして、シンプルなアイデアも結局はほぼ現実には使えないものだったと判明する。 C++への機能追加は非常に大変だ。新しい機能を提案した者は、それが受け入れられるまでに大変な苦痛を強いられる。 だが、一度受け入れられたなら、新しい機能はこの巨大なコミュニティに大きな影響を与えることができる。 もしわしがこの世界にインパクトを与えるまいとするなら、わしはtoy-programming言語をデザインしたり、フィクションを書いたり、クロスワードパズルを解いたりして、わしの知的好奇心をなだめていただろう。

    ああ。わしはC++よりも先進的で、コンパクトで、優れた言語をデザインしたいと思っている。 しかし、(新しい言語で解決される)問題や、新しい言語がもたらす影響を見るたび、「それC++でできるよ!」と思ってしまうのだ。

    少なくともわしは、プログラミングの世界によい影響を与えたければ、そのために新しい言語をデザインし、実装し、広めるよりも、C++のようなよくならされた道から発信するほうが容易だと思うがの。

  • DK Unicodeサポートに関してですが、C++0x規格には、Unicode文字列をコード化するUTF16、UTF32で動くようにするために、u16string と u32string と同様に char16_t や char32_t が含まれます しかし、標準streamライブラリはこのあたりをサポートしていません。 u16coutやu32coutみたいなものがありませんし。 いったい、どうやってchar16_t を使えばいいのか、どうやって標準出力に書き出せばいいのかわからないのですが。
  • BS 標準ライブラリにUnicode streamと、広範なUnicode サポートはあってしかるべきだな。 もちろん、標準委員会はこのことを理解しておる。だが、誰もこの難儀な仕事をやってのけるスキルと時間に恵まれたものがおらなんだ。そうして、プログラマが”サードパーティ”サポートを探しまわる問題領域となってしまったのだ。不幸なことだの。 “標準の外側に”行けばUnicodeをしっかりサポートしたライブラリが見つかる。 例えば、だ。”network とインターネットベースのアプリケーション構築用の”Poco(http://pocoproject.org/index.html)などどうだろう。これはboost のopen-source licenseの元配布されておる。 ほかにも、Microsoft C++サポートライブラリ(のどこか)にUnicodeがサポートされておる。

    標準ライブラリがUnicodeライブラリをサポートしていないのは残念なことだ。しかし、ほとんどのライブラリは標準になく、また標準入りできない事も覚えておかねばならんの。 わしのC++ホームページにはライブラリやライブラリのコレクション、ライブラリのリストへのリンクが多く貼られておる。 “標準ライブラリ外”(商用・オープンソース合わせて)には一万を超えるライブラリがあるとの見積りもなされておる。 問題はどうやって探して評価するか、だの。

  • DK 最後に、新年の抱負をお聞かせください。
  • BS
    • C++0xの正式なISO標準採択
    • C++ Programming Language (4th Edition)の草稿を仕上げる
    • 孫たちともっと遊ぶ
    • 少なくとも一つ、新しい技術的見識を得る

  1. stillpedant reblogged this from zakkas783
  2. tyru-tech reblogged this from zakkas783
  3. cr96 reblogged this from haseshin
  4. take-cheeze reblogged this from zakkas783
  5. haseshin reblogged this from iorionda
  6. cryolite reblogged this from zakkas783
  7. iorionda reblogged this from zakkas783
  8. junary reblogged this from zakkas783
  9. memoarchive reblogged this from zakkas783
  10. swanky-days reblogged this from zakkas783
  11. scilm-k reblogged this from zakkas783
  12. akisuteno reblogged this from zakkas783
  13. unkei3 reblogged this from zakkas783
  14. dr-caligari reblogged this from zakkas783
  15. eldesh reblogged this from zakkas783
  16. do-nothing reblogged this from zakkas783
  17. zakkas783 posted this