Boost.1.52とかでshared_mutexがlock_error例外投げたりしたんだけど

これだった。
https://svn.boost.org/trac/boost/ticket/7720

Windows環境の人は BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN を定義してねって。
Windows上のなんかの実装だとちょっとバグ出るわーでも汎用的な実装では修正済みだわーだからこのマクロ追加したんだわー1.53からはデフォルトで定義するようにするわー的なこと言ってる

Boost.ThreadのドキュメントのUsing and building the libraryのConfigurationの辺りに詳しいこと書いてた。
http://www.boost.org/doc/libs/1_52_0/doc/html/thread/build.html

[追記]
汎用的な実装の方は遅いそうで、Boost.1.53ではデフォルト指定されませんでした。
https://svn.boost.org/trac/boost/ticket/7906

[追記]
https://svn.boost.org/trac/boost/ticket/7720#comment:15
このパッチを当てて修正すれば、lock_error例外が投げられなくなるので、上記のマクロを定義しないでも大丈夫そう。(ちらっと試した感じでは大丈夫だった。)
trunkにはコミットしてあるらしいので次のboost 1.54とか修正されているでしょうか。

規格書を読もう

この記事はC++ Advent Calendar 2012の参加記事です。

初めに

みなさんはC++を書いているときに分からないことが有ったらどうやって調べているでしょうか。
おそらくブラウザの検索窓に「C++ ポインタ」とか「C++ テンプレート」とか「C++ 闇」とかカチャカチャ入力してエンターキーをッターン!してるでしょう。僕もです。

C++やBoostについて書いているサイトは日本語でもたくさんありますし、とてもありがたいことに、包括的に解説してくれているところさえ有ります。非常に重宝します。

さて、C++を勉強していきSTLやBoostなんかも使い始め、寝ても覚めてもC++のことが頭から離れなくなってきたのであれば、C++について調べる方法として、C++の規格書を選択肢に加えるのもいいかもしれません。

C++の規格書とは、プログラミング言語 C++を定義し、この言語を実装する実装系に対する要求を指定しているものです。
現行規格のISO/IEC 14882:2011は1300ページ超もあり、この中に、C++という言語に関する様々な定義が詰まっているのです。

規格書を参照するといい理由

なぜ、C++について調べる方法として、C++の規格書を選択肢に加えるとよいのでしょうか。
それは、規格書に書いてある内容こそがまさしくC++だからです。

なにか分からないことがあったときに一次情報を探すのはいいことです。
C++の一次情報である規格書を読むことで、もっとも基本的な部分から、バイアスを受けずにC++を知ることができます。

C++の規格は巨大であると言われます。
しかし、規格を読むといっても、その全ページを順に読んでいく必要は有りません。
規格書は、言語機能やライブラリの定義など、いくつかのClause(節)に分けて構成されています。C++のある機能について調べようとすると、規格書の中でその機能について書かれた部分と、必要であればさらにそれに関連する項目を読んでいくことになります。

それでは実際に規格書を読んでみましょう。とは言っても僕自身、C++11の規格書自体は持っていません。僕が持っているのは、最新のC++規格(通称C++11)が公開されたあとに公開されたpaper N3337です。これは公開された規格と内容がほぼ同一で、むしろtypoの修正等さえ含まれています。そのため、実質的にこれをC++11とみなしてしまって問題ないでしょう。

規格書の構成

規格書はClause 1ではこの規格の根幹部分が書かれ、その後の節の前半では主にC++という言語について、後半では主にC++の標準ライブラリについて書かれています。
前述のとおり、規格書はいくつかのClause(節)に分かれています。
各節の下にさらに細分化されたセクションが設けられていることがあり、それぞれに[expr.prim.lambda]のような階層構造状のラベル名が付けられています。

トップレベルのセクションはこのようになっています。

1. General
    この規格が扱う領域や用語や記法、C++のメモリモデルやC++のオブジェクトモデル、この規格が想定するプログラムの実行やマルチスレッドとは何か、など、C++の規格の最も根幹にあたる部分が書かれています。

2. Lexical conventions
    ソースファイルの定義や、トークンやキーワードといったC++の字句に関する規約について書かれています。

3. Basic concepts
    Declaration、Definition、スコープ、リンケージ、value categoryといった、プログラミング言語 C++の基本的な概念について書かれています。
    ここで紹介する概念には、言語の一部分にだけ影響するようなものは含まず、そのような概念はあとに続く節で書かれています。

4. Standard conversions
    char型の値をint型に昇格したり、配列を先頭要素を指すポインタに変換したりする、標準変換と呼ばれるルールについて書かれています。

5. Expressions
    Expressions(式)について書かれています。
    関数の呼び出し、各種演算子、constexprなどの定義やはたらきはここに書かれています。

6. Statements
    Statements(文)について書かれています。
    if文やswitch文といった制御構文や、宣言を行う宣言文などについて書かれています。

7. Declarations
    プログラム上に名前を導入し、その名前が表すものがどのように解釈されるかを指定する、Declarations(宣言)について書かれています。
    staticやtypedefなどのSpecifiers(指定子)や、enum名前空間の宣言はここに書かれています。

8. Declarators
    Declarationのうち、単一の変数や関数などを宣言する、Declarator(宣言子)について書かれています。
    変数やポインタや参照変数を宣言するための構文や、初期化子、関数定義などはここに書かれています。

9. Classes
    クラスについて書かれています。
    クラス定義の文法や、クラスのメンバについて書かれています。

10. Derived Classes
    クラスの継承や仮想関数について書かれています。

11. Member Access Control
    クラスのメンバへのアクセス指定子について書かれています。

12. Special Member Functions
    コンストラクタやデストラクタなど、特殊な働きをするメンバ関数について、また、クラスの初期化やexplicitなどについて書かれています。

13. Overloading
    関数や演算子のオーバロードとオーバーロード解決のルールなどについて書かれています。

14. Templates
    テンプレートについて書かれています。
    クラステンプレートや関数テンプレートの定義や特殊化についてはここに書かれています。

15. Exception handling
    try、catch、throwや例外指定、std::terminate関数など、例外を扱うための仕組みについて書かれています。

16. Preprocessing directives
    #includeや#defineや定義済みマクロなど、プリプロセス命令について書かれています。

17. Library introduction
    以降で書かれるC++標準ライブラリの導入のための節です。
    C++標準ライブラリの俯瞰的な説明や、C標準ライブラリとの関係、ライブラリの節で使用される用語の定義などが書かれています。

18. Language support library
    実装系の特性が定義されたヘッダや、動的メモリ管理、初期化子リストで使用されるlinitializer_listの定義など、言語機能を支えるクラスや関数について書かれています。

19. Diagnostics library
    アサーションや例外クラスなど、エラーを発見しレポートするためのライブラリについて書かれています。

20. General utilities
    tupleやpairなどのクラス、swapやmoveなどの関数、関数オブジェクト、スマートポインタ、時間ライブラリなど、基本的な役割のクラスや関数について書かれています。

21. String library
    文字列クラスや、数値変換、NULL終端文字列用の関数について書かれています。

22. Localization library
    Localeクラスや、codecvt_*クラスなど、Localizationのためのクラスや関数について書かれています。

23. Containers library
    std::vectorやstd::unordered_mapやstd::stackなど各コンテナ、コンテナアダプタの定義とコンテナが満たすべき要件について書かれています。

24. Iterators library
    コンテナやストリームをイテレートする仕組みであるイテレータが満たすべき要件や、iterator_traitsクラス、イテレータアダプタなどについて書かれています。

25. Algorithm library
    コンテナやなんらかのシーケンスに対してalgorithmicな操作を行う関数について書かれています。

26. Numerics library
    数値型が満たすべき要件や、複素数、乱数、数値向けのalgorithmicな操作を行う関数など、数値に関するクラスや関数について書かれています。

27. Input/output library
    ストリームバッファ、ファイルに対する出入力ストリームなど、出入力に関するクラスや関数について書かれています。

28. Regular expression library
    正規表現を扱うためのクラスや関数について書かれています。

29. Atomic operation library
    std::atomicクラスやメモリフェンスなど、アトミック操作のためのクラスや関数について書かれています。

30. Thread support library
    std::threadクラスやstd::mutexクラスなど、マルチスレッドのためのクラスや関数について書かれています。

付録A
    C++の文法の要約です。
    C++の文法は前半の言語機能の章で幾つかの箇所に散らばって定義されているため、この付録にて文法だけがまとめられています。

付録B
    インクルードファイルのネスト回数やテンプレート引数の数など、実装系における量的な制限のガイドラインについて書かれています。

付録C
    ISO CやISO C++ 2003との互換性について書かれています。
    特にISO C++ 2003との互換性についてはめるぽんさん(@melponn)による要約がこちらにあります。http://d.hatena.ne.jp/melpon/20110826/1314343549

付録D
    deprecatedであったり、既存の実装系に対する互換性のために存在する機能について書かれています。

付録E
     識別子に使用できる、あるいはできないUniversal Characterについて書かれています。

付録F
    [expr.prim.lambda]のような各セクションのラベルからセクション番号を参照するクロスリファレンスです。

Index
    function、entity、ECMA-262といった語句からページを参照する索引です。

Index of grammar productions
     文法の生成規則の定義に現れる名前からページを参照する索引です。

Index of library names
    ライブラリに存在する名前からページを参照する索引です。

Index of implementation-defined behavior
    実装定義の振る舞いに関する名前からページを参照する索引です。

規格書を参照する

実際に規格を参照して、C++に関する疑問を解消してみましょう。

例1

もしもあなたが、C++で使われるオブジェクトという用語(例えば「pointerに対して*(参照演算子)を適用した式は元のオブジェクトのlvalueを返す」など)がどうしても気になった場合は、規格書を参照しましょう。
なにせ、「C++ オブジェクト」などとGoogle検索しようものならあなたはすぐさまOOPの巨大な波に飲み込まれて貴重な2時間をGoogle検索の「次へ」ボタンを押す作業に費やすことになるでしょうから。
ところがN3337を参照すると、1.8にC++ object modelなるステキなタイトルのセクションが見つかるじゃないですか。そして1.8/1には「The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a region of storage.」なるステキな記述が。やったね!
規格を参照すると、C++という言語について知りたい情報にダイレクトにアクセスできます。

例2

あるいは、range-based forがどのように働くかを調べたければ、6.5にあるIteration statementsから6.5.4 The range-based for statementsを参照します。
そしてそこには

for ( for-range-declaration : expression ) statement

for ( for-range-declaration : braced-init-list ) statement

の形式のrange-based for文が

{
    auto && __range = range-init;
    for ( auto __begin = begin-expr,
          __end = end-expr;
          __begin != __end;
          ++__begin ) {
        for-range-declaration = *__begin;
        statement
    }
}

と同等であると明記されています。そして続く説明にて、より詳しい解説がなされています。
このように規格を参照すると、C++の各機能がどのように働くかをより深く理解できるのです。

例3

また別の例で言うと、コンテナの各関数については、

ExpressionReturn typeAssertion/note
pre-/post-condition
a.insert(p,i,j) iterator Requires:T shall be EmplaceConstructible into X from *i.
For vector, if the iterator does not meet the forward iterator
requirements (24.2.5), T shall also be MoveInsertable into
X and MoveAssignable. Each iterator in the range [i,j) shall be
dereferenced exactly once.
pre: i and j are not iterators into a. Inserts copies of elements in [i, j) before p

このように各関数が満たすべき要件(requirements)が明示されています。そしてさらにこまかい挙動をする関数やアルゴリズムライブラリの関数はそれぞれの関数の定義のところで、事前条件、事後条件、例外保証、計算量(複雑性)等が明示されています。
これらは多くのC++の解説では省略されてしまって、普段は意識することがないかもしれません。しかし、これらに気をつけてプログラムを書けば、C++を使う上でのミスを減らし、罠を避け、効率的なプログラムを書くことを可能にします。
規格を参照すると、C++力が上がるのです。

おわりに

規格書は普段から読み続けなければならないものではないですが、しかしC++を毎日ガリガリガシガシ触っているのであれば、たまに(いつも?)どこか分からないところが出てきたりして、自然に開いてしまっている、そんなモノだと思います。

規格書はすべて英語で書かれているので読むのは難しいですが、日本語訳を公開しているプロジェクトもありますし、ちょっと内容が古いですが、C++ ARM(Annotated Reference Manual)の日本語版「注解C++リファレンスマニュアル」を探してみるのもいいかもしれません。そして訳と共に原文を見ながら定義されたそのままのC++に触れてみるのはいかかがでしょうか。今よりもC++がくっきりと見えてくるかもしれません。

謝辞

励ましてくれた[twitter:@lapis_tw]さんとアドバイスを頂いた[twitter:@bolero_MURAKAMI]さん。

そして

執筆が遅れてしまって申し訳ありません!
次は[twitter:@hr_sao]さんです!

C++ ポインタ ブートキャンプ

Sapporo.cpp & CLR/H 合同勉強会 : ATNDで僕は、「C++ ポインタ ブートキャンプ」というタイトルでセッションを行いました。
30分頂いた時間枠に収めるために、分量的にはポインタの限定的な紹介にとどまりましたが、ポインタの基礎的な部分を、無駄な抽象化をせずに説明するように心がけました。

ポインタの解説に当たって9枚目のポインタの定義「ポインタとは何らかのオブジェクトを指すオブジェクト」は大事だと思っています。よくポインタは変数を指すであるとか、メモリを指すであるとか言われますが、ポインタが指すのはあくまでオブジェクトです。これについては別エントリでまとめます。*1

また、addressof()とindirect()という仮想的な機能を用いた擬似コードによるポインタのセマンティクスの話も大事だと思っています。つまりaddressof()とindirect()という仮想的な機能を想定し、これがあれば変数を使用せずにオブジェクトを操作できること、アドレスの取得と間接参照、そして実際のコードではどのようなコードに置き換わるのか。
これは関数ポインタという特殊なポインタを除いて、すべてのポインタで共通の概念ですので、このセマンティクスを念頭に置いておくとポインタの理解の助けになるのではないかと思います。

理想的には参照とスマートポインタをもう少し細かく解説もしたかったのですが、スライド作成の時間と、発表時間の都合上軽く紹介するだけにとどめました。

というわけで、ポインタについて、自分ならこう捉えるというのをまとめたスライドになりますが、もし間違いがあったら指摘を頂けるとありがたいです。

*1:ちなみに、僕のスライドも当初9枚目10枚目でそのような表現を使ってしまっていました。修正済み

東方神居祭6に参加しました

大学のDTMサークルの有志でアレンジCDを製作し、東方神居祭6にサークル参加してきました。

去年の東方神居祭4(東方神居祭4に参加してきた - How to disappear completely)に続いて2度目の東方神居祭参加となりました。

今年は[twitter:@green_ran]がプロジェクトリーダーとしてこの企画を引っ張っていってくれたおかげで参加ができました。みどらんありがとうー

イベントでは「Toneless Twilight Tunes」という東方アレンジCDを頒布しました。
僕も「東方妖々夢 〜 Ancient Temple」のトランスアレンジとして「Trancient Temple」というタイトルで一曲参加しております。(プレビュー版はこちらTrancient Temple(preview) by hotwatermorning | Free Listening on SoundCloud

ちゃんとしたトランスを作るのは初めてだったのでまだ習作って感じもあったり、詰めの時間が足りなかったなーなんて、今から考えるとそう思う部分もありますが、去年よりは良いクオリティの作品になったと思います。

というか、去年のCDと比べて全体的なクオリティが上がっていてよかったと思います。

ちなみに、


当日は他のサークルさんも沢山CD出してたし人も多かったし友人にも見に来てもらえたし楽しかった。

こういったちゃんと曲を作る機会があるとDTM力も上がるし、DAWの使い方も覚えるし、みんなの曲も聞けるし、非常にいいものですね。(今回曲製作するにあたって、Ableton Liveのクリップをクロップっていう機能と、オーディオクリップの録音機能の使い方を知りました。)

Visual Studio 2008のデバッグでステップ実行が遅い件

1ステップ実行するのに2秒くらいかかることがあって非常にやきもきしていた。
「ソースのスレッドを表示する」が有効になってた。
これを外したら早くなった。
めでたしめでたし。