2014-02-17

2014-01-pre-Issaquah mailingの簡易レビュー Part 1

今回は、論文の本数が多いのと、ドワンゴに雇われているので、本気でじっくりと論文を読んで解説しているし、ライブラリの論文も読み飛ばさずに読んでいるので、いつもより時間がかかる。そのため、いくつかのパートに分けて公開することにした。

今回はドラフトの更新はなし。

今回の新機能の提案の論文には、SG10のためのマクロ名の提案が目立つ。SG10というのは、Cプリプロセッサーによる機能テストのマクロ名を標準化しようという提案のStudy Groupだ。醜悪で将来廃止されるべきCプリプロセッサーに依存する機能をこれ以上増やさないで欲しいのだが。

N3824: make_array

std::array<T>を返すmake_arrayの提案。以下のように使う。

// make_arrayの利用例
std::array<int, 3> a = std::make_array( 1, 2, 3 ) ;
std::array<long, 2> b = std::make_array( 1, 2L ) ;

どの型になるかは、std::common_typeを使って決定される。ただし、narrowing conversionは禁止されている。

// narrowing conversionは違法になる
auto a = std::make_array( 1, 2U ) ; // エラー

明示的に型を指定することで、キャストされる。

// 明示的に型を指定する例
auto a = std::make_arrary<long>( 1, 2U ) ; // OK

もちろん、現実に書くときには、auto指定子を使うべきだ。

// make_arrayの利用例
auto a = std::make_array( 1, 2, 3 ) ;
auto b = std::make_array( 1, 2L ) ;

[PDFを廃止する議論が必要とされている] N3825: SG13 Graphics Discussion

C++14に標準ライブラリとして入れるために設計を進めている軽量グラフィックライブラリの土台として、何を使うかの議論のまとめ。

C++にグラフィックライブラリを入れたいが、グラフィックライブラリを一から設計するのは、C++標準化委員会の規模を大幅に超えているので、既存のグラフィックライブラリを土台として使い、必要であればC++風にバインドして使おうというのが、これまでの議論。では、その土台を何にするかというのが、この議論の主題だ。

土台には二つの意見があった。既存の規格を使うものと、既存のライブラリを使うものだ。

既存の規格というのは、例えばSVG+Canvasのような、標準規格を参照して、その設計を元にC++風にバインドして使うということだ。

既存のライブラリというのは、例えばcairoのような、すでに実装されているライブラリを元にして、必要であればC++風にバインドして使うということだ。

どうやら、議論の方向は既存のライブラリ、それもcairoを土台とするところに向かったらしい。cairoはCで書かれているが、オブジェクト指向であり、正しくconstを使っており、またドキュメントも非常に充実している。

cairoには、cairommというC++へのバインドがあるが、どうもこのcairommは、2010年から更新されていないので、おそらくプロジェクトとしては死んだのではないかと思われる。

そこで、cairo本体を土台とし、数ページ程度に収まるような機会的な変換ルールを定義して、cairoのインターフェースをC++風に合わせてはどうか。論文では、そのための変換ルール案も箇条書している。また、cairoのドキュメントなどがISO規格として使えるような著作権許諾が得られるかなどの調整も必要だ。

本当にC++14の標準ライブラリにグラフィックライブラリが入るのだろうか。

N3827: Working Draft Technical Specification - URI

URIライブラリのドラフト

[汚いPDF] N3829: apply() call a function with arguments from a tuple (V2)

tupleの要素をすべて関数の実引数に渡すライブラリー、applyの提案。

これは欲しい。自前で実装するのは簡単だが、面倒だ。

N3830: Scoped Resource - Generic RAII Wrapper for the Standard Library

汎用的なRAIIラッパーライブラリー、scoped_resourceの提案。

RAIIというのは、Resource Acquisition Is Initializationの略である。C++では、クラスオブジェクトにリソースを所有させ、デストラクターが動くタイミングで解放処理をさせるような一連の技法を言う。

// RAIIの例
class raii_holder
{
    int * owned ;
public :
    explicit raii_holder( int * ptr )
        : owned( ptr ) { }

    raii_holder( raii_holder const & ) = delete ;    
    raii_holder & operator =( raii_holder const & ) = delete ;

    int * get() { return owned ; } 

    ~raii_holder()
    {
        delete owned ;
    }
} ;


int main()
{
    raii_holder r( new int(0) ) ;
    *r.get() = 123 ;

// 自動的にdeleteされる
} 

ポインターの場合は、すでにunique_ptrがあるが、ポインター以外のリソースを管理するライブラリは、手で書くしかない。unique_ptrは、ポインター以外のリソース(単なる整数値で表現される環境依存のハンドルなど)を管理するのは面倒だ。

問題は、このようなRAIIラッパーを手でいちいち書くのは面倒だ。これは、テンプレートで汎用化すべき種類のコードだ。C++14までのコア言語機能を総動員し、最新の設計をすれば、そのような汎用RAIIラッパーライブラリが実現できる。

// 提案中のライブラリ
int main()
{
    auto r = std::make_scoped_resource( &::operator delete, new int(0) ) ;

// 自動でdeleteされる。
}

まだ設計は変わるが、このライブラリは非常に柔軟である。例えば、解放のための処理が、単に引数をひとつとるものではない場合がある。たとえば、以下のような実装依存のリソースの確保、解放関数があったとする。

// System defined APIs:
void* VirtualAlloc(
void *pAddress,
size_t size,
unsigned int fAllocationType,
unsigned int fProtect);

bool VirtualFree(
void *pAddress,
size_t size,
unsigned int uiFreeType);

これはこのようになっているので、いまさらどうしようもない。提案中のscoped_resouceでは、これを単に、複数のリソースをまとめて管理するという形で扱う。わざわざユーザーがVirtualFreeと複数のリソースをラップする必要はない。

// VirtualFreeにもらくらく対応
int main()
{
    auto r = std::make_scoped_resource( &VirtualFree,
        VirtualAlloc( nullptr, PAGE_SIZE, MEM_COMMIT, PAGE_HARDWARE ),
        0,
        MEM_RELEASE ) ;

// 自動的にVirtualFree
}

Variadic Templatesを使えば、任意個のリソースを管理できる。

実は、管理するリソースは、0個でも良い。

// 0個のリソースを管理する例
int main()
{
    auto r = std::make_scoped_resource(
        []{ std::cout << "I'm exception safe. Thank you very much." << '\n' ; }
    ) ;

// 自動的にlambda式が呼ばれる
}

これにより、オブジェクトrが破棄されるタイミングで処理を実行することもできる。

このようなライブラリを手で書くのは簡単だが、正しく書くのは面倒なので、標準ライブラリに入って欲しい。

この提案では、あくまでunique_ptrをポインター以外にも広げたscoped_resourceを提案している。参照カウンターを使ったものは提案されていない。そのようなライブラリも実装可能だが、この論文では、それは後から検討する話だとしている。追加は簡単なので、とりあえずはこれを議論したほうがいい。

[気分を害するPDF] N3831: Language Extensions for Vector level parallelism

Clik PlusやOpenMPで提供されている、プログラムにSIMD化のためのヒントを与える構文の提案。

SIMD化できるループは、極めて厳しい制約が課される。論文ではこれをcountable loopと呼んでいる。

SIMD loopをコア言語でサポートするために、for文に変更がくわえられる。

// SIMD loop
for simd ( int i = 0 ; i < 10 ; ++i ) 
{
// 処理
}

キーワードsimdは、文脈依存キーワードなので、この文脈でなければ予約されていない。そのため、自由に識別子として使うことができる。

for文の条件式につかえる式は、非常に限られている。以下の組み込みの演算子しか使えない。

// SIMD forの条件式で使える式
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
equality-expression != relational-expression

また、for文の3つ目のオペランドにも、前置後置のインクリメントとデクリメント、+=, -=, E1 = E2 + E3, E1 = E2 - E3ぐらいしか使えない。これは組み込みのコンマ演算子で区切ることができる。その中で使える識別子で参照されているものにも、強い制約がある。

return, break, goto, switchなどを使って、ループの中から外に脱出したり、また外からループの中に飛び込んだりすることはできない。

また、SIMD関数というものもある。これは、文脈依存キーワードsimdでマークされる関数のことである。

// SIMD関数の例
int f() simd { }
[]() simd { } ; // もちろんlambda式にも使える

さて、このようにsimdキーワードでマークされたループや関数には、複数のコードが生成され、実行時にふさわしいものが選ばれる。つまり、これはコンパイラーへのヒントである。

[理論的に美しくないPDF] N3832: Task Region

C++でstrict fork-joinを実現するためのライブラリ。

こうしてみると、並列処理というのは、理論が数十年ぐらい先行していて、いま、ようやく理論をC++のような実用的な言語で使うために、現実の場に落としこんできているというのがわかる。このライブラリはかなり理論よりの内容になっているが、はたしてここまでガチガチの机上の理論に裏打ちされたライブラリが、普通のプログラマーに簡単に使えるようなライブラリに落ち着くだろうかという懸念はある。

原理としては、task_regionに関数オブジェクトを渡して、その中で並列実行したいタスクはtask_runに関数オブジェクトを渡して実行するということになっている。そして、最後にすべての並列処理をjoinして集める。

ただしこれはかなり理論的なライブラリなのでかなり制約がなくす方向で進んでいる。たとえば、関数を呼び出した時のスレッドと関数が戻ってきた時のスレッドが異なることは、従来起こりえないことだったが、このライブラリでは、起こりえてしまう。これをどうしようかということが議論されている。また、まだ完全に処理が終わらない状態で関数が戻るということもあるので、その場合をどうしようかという議論もある。

[PDF不使用原則も提案したい] N3839: Proposing the Rule of Five, v2

従来の三原則に変えて、五原則を導入する提案。

三原則とは、コピーコンストラクター、コピー代入演算子、デストラクターの、どれかひとつをユーザー定義した場合、残りの二つも、おそらくはユーザー定義が必要になるであろうという原則だ。

C++11では、ムーブという概念が、直接コア言語に組み込まれた。当初、ムーブを直接コア言語でサポートするかどうかは、決まっていなかった。しかし、ムーブのような基本的な概念は、コア言語で認識したほうがいいだろうという結論になり、従来のコピーコンストラクター、コピー代入演算子にくわえて、ムーブコンストラクター、ムーブ代入演算子が、新たにコア言語で特別なメンバー関数として認識されるようになった。

もし、C++11で、ムーブコンストラクター、ムーブ代入演算子がユーザー定義されていた場合、コピーコンストラクター、コピー代入演算子は、暗黙にdefault化される。この挙動はdeprecatedであり、将来的には廃止される見込みに、C++11ではなっていた。

さて、C++14では、十分に猶予を与えたし、そろそろ廃止してもよかろうという論調になってきた。すなわち、五原則の成立だ。コピーコンストラクター、コピー代入演算子、ムーブコンストラクター、ムーブ代入演算子、デストラクターの5つの特別なメンバー関数のうち、どれかひとつをユーザー定義した場合、残りもユーザー定義しなければならない。なぜならば暗黙にdefault化されないからだ。

// 五原則の例
struct X
{
    ~X() { }
} 

int main()
{
    X x1 ;
    X x2 = x1 ; // エラー、五原則
}

ただし、五原則を導入すると、既存のコードで、暗黙の宣言に頼っているコードが壊れてしまう。C++規格では、互換性を壊す変更は、相当に慎重になるので、すでにdeprecated扱いになったとはいえ、たやすく消すことはできない。文字列リテラルから暗黙にconst性を失わせる仕様の除去にも、15年かかった。

// 文字列リテラルからconst性をなくす例
int main()
{
    // well-formed in C++03
    // ill-formed in C++11
    char * ptr = "hello" ; 
}

この五原則は、ぜひともC++14に入って欲しい。deprecated仕様は、もう何年もの猶予を与えたのだから、十分すぎる。

[PDFは世界一おバカなフォーマット] N3840: A Proposal for the World's Dumbest Smart Pointer, v3

世界一おバカなスマートポインター、observer_ptrの提案。

生のポインターというのは、意図がわかりにくい。たとえ、所有して管理という概念がないとしても、ポインタークラスを標準ライブラリに入れたほうがいいのではないか。そうすれば、そのオブジェクトは管理されていないポインターであるという意図が明確になる。

// observer_ptrの例
#include <memory>

int main()
{
    // std::observer_ptr<int> ptr = new int(0) ; と同じ
    auto ptr = std::make_observer( new int(0) ) ;

    auto p2 = ptr ; // コピーできる

    delete ptr ;
}

observer_ptrは、ポインターを所有しないし、管理することもない。そのため、自由にコピーもできる。ポインターが動的に確保されたストレージをさす場合、その解放は利用者の責任である。

生のポインターを直接使うより、意図がわかりやすくなる。ただし、別に生のポインターでもわかりにくくならないのではないかという標準会員の重鎮もいるし、議論は分かれている。

[PDFの使用も非推奨] N3841: Discouraging rand() in C++14

std::random_shuffleとstd::randを非推奨にする文面を追加する提案。

std::randは、とてつもなく使いにくい設計であり、広く誤用されている。例えば、以下のような間違ったコードが使われている。

// 間違ったサイコロの実装
int roll( )
{
    return std::rand()%6 + 1 ;
}

このコードは間違っている。なぜならば、剰余は均一分布しないからだ。ある乱数から、特定の範囲の値を数学的に信頼できるほどの精度で均一分布させたい場合は、もっと工夫が必要になる。このような間違ったコードは、世の中のソフトウェアに乱用されていて、世の中のソフトウェアに正しくない乱数をもたらしている。このような誤用をしやすい時代遅れの設計のstd::randは、使用を非推奨にすべきである。

また、イテレーターの組の中の要素を、ランダムにシャフルするアルゴリズム、std::random_shuffleも、std::randの利用を前提にしたオーバーロードがあり、また、独自の乱数を渡す部分も、非常に汚い設計になっているので、これも同じく非推奨にする。

規格では、注記として、「randの使用は、故に、移植性がなく、予期できず疑わしい品質とパフォーマンスである」と書かれるようになった。

読者は、std::randやstd::random_shuffleのような時代遅れの設計のライブラリを使ってはならない。std::randの代わりには、C++11に新しく入った素晴らしい設計の乱数ライブラリを使うべきであるし、std::random_shuffleの代わりには、C++11で新しく追加されたstd::shuffleを使うべきである。

[標本採取されないべきPDF] N3842: A sample Proposal

sample(標本採取)というアルゴリズムの追加。このアルゴリズムは、値の集合の中から、ランダムで一部を取り出すものである。このアルゴリズムは、Knuth先生のThe Art of Computer Programming, Volume 2で、アルゴリズムS(“selection sampling technique”) とアルゴリズムR(“reservoir sampling”)と呼ばれている。

ちなみに、vol. 2でアルゴリズムBと呼ばれているのは、C++11に入った<random>にある、std::knuth_bである。

アルゴリズムS(Selection sampling)は、標本を採取する値の集合は、Forward iteratorを必要とし、採取した標本を書き出すイテレーターには、Output Iteratorを必要とする。

アルゴリズムR(Reservoir sampling)は、標本を採取する値の集合は、Input Iteratorを必要とし、採取した標本を書き出すイテレーターには、Random Access Iteratorを必要とする。

提案では、アルゴリズムS版とR版で名前を分けるのではなく、実引数に渡したイテレーターのカテゴリーにより、タグディスパッチをして自動的に適用可能なアルゴリズムを選ぶ設計になっている。


template< class PopIter, class SampleIter, class Size, class URNG >
SampleIter
sample( PopIter first, PopIter last, SampleIter out, Size n, URNG&& g )
{
    using pop_t = typename iterator_traits<PopIter>::iterator_category;
    using samp_t = typename iterator_traits<SampleIter>::iterator_category;
    return __sample( first, last, pop_t{},
                     out, samp_t{},
                     n, forward<URNG>(g) );
}

Knuth本のアルゴリズムRは、安定しているが、追加の処理が必要になる。SGI版のSTLにあるsampleアルゴリズムは、不安定だが追加の処理をしない。論文ではこの点を注記しているが、C++のアルゴリズムR版のsampleが、どのように実装されるかについては言及していない。

[江添フレンドリーではないPDF] N3843: A SFINAE-Friendly std::common_type
[江添フレンドリーではないPDF] N3844: A SFINAE-Friendly std::iterator_traits

std::common_typeと、std::iterator_traitsをSFINAEフレンドリーにする提案。

たとえば、以下のようなコードは、C++11では違法(コンパイルエラー)になる。

// C++11では違法
using type = std::common_type<int, int *>::type ;

なぜならば、int型とint *型には、共通の変換できる型がないからだ。

しかし、このようなコードが違法になると、SFINAEの文脈で、問題になる。

// SFINAEとはならない例

// 共通の型がある場合のみ候補に上がるべき関数テンプレート
template < typename T1, typename T2,
    typename COMMON_TYPE = std::common_type<T1, T2>::type >
void f( T1, T2 ) { }

// その他の関数fのオーバーロード

int main()
{
    int a1 = 0 ;
    int * a2 = nullptr ;

    f( a1, a2 ) ; // コンパイルエラー

} 

このコードでは、SFINAEを使って、共通の型がある場合のみ、オーバーロード解決の候補に上がるテンプレート関数fを宣言しようとしているが、残念ながら、common_typeは共通の型がない場合、内部でill-formedになってしまうので、このコードは通らない。

N3843は、共通の型がない場合にも、内部で勝手にill-formedにならず、しかもSFINAEの文脈で使えるよう、ネストされた型名を宣言しないように、std::common_typeを変更しようという提案だ。

これと全く同じ理由で、std::result_typeは、以下の提案論文の採択により、すでにSFINAEフレンドリーに変更されている。

N3462: std::result_of and SFINAE

result_typeと同様に、common_typeとiterator_traitsもSFINAEフレンドリーになるべきである。この提案は採択されてほしい。

ちなみに、この論文には、ブインの提督、銀天すばる (SubaruG)さんがこの問題を取り上げたブログ記事にも言及している。

A Blog Post
Although written in Japanese, the author shows an invoke function defined with result_of that fails to compile because it (result_of) is not SFINAE-friendly. It also calls out std::common_type as another trait that would benefit from being SFINAE-friendly.

FDIS の不満点 - 野良C++erの雑記帳

現状、 std::result_of や std::common_type といった「型を取得するメタ関数」は、与えられた型が前提条件を満たさない場合、クラステンプレートの内部でコンパイルエラーとなるため、 SFINAE に使うことが出来ません

[PDFは割り切れない思い] N3845: Greatest Common Divisor and Least Common Multiple

最大公約数を計算するgcdと、最小公倍数を計算するlcmを<cstdlib>に追加する提案。

最大公約数や最小公倍数のアルゴリズムは、義務教育でも習うほど初歩的なものであるが、たとえ実装が一行にせよ、コードを書いて、正しく動くかどうかテストするのは難しい。しかも、このような基本的な関数の用途はかなり広い。標準ライブラリに存在するべきだ。

提案されているgcdとlcmは、constexpr関数かつ関数テンプレートで、二つの整数型の引数を取る。

また、gcdとlcmを実装するために、constexpr関数でテンプレート関数版のabsも追加される。

その実装は、コード量だけで言えば、とても短い。この記事に引用できるほどだ。

// N3845のリファレンス実装例
// 仮にclib名前空間内に置く
namespace clib {

// 任意の整数型で動くテンプレート版のabs
template< class T >
constexpr auto abs( T i ) -> enable_if_t< is_integral<T>{}(), T >
{
    return i < T(0) ? -i : i; }
}

// 二つの実引数が整数型であるかどうかを確認し、また共通の型を返すメタ関数common_int_t
template< class M, class N = M >
using common_int_t = enable_if_t< is_integral<M>{}() and is_integral<N>{}()
, common_type_t<M,N>
> ;

// 最大公約数
template< class M, class N >
constexpr auto gcd( M m, N n ) -> common_int_t<M,N>
{
using CT = common_int_t<M,N>;
return n == 0 ? clib::abs<CT>(m) : gcd<CT,CT>(n, m % n);
}

// 最小公倍数
template< class M, class N >
constexpr auto lcm( M m, N n ) -> common_int_t<M,N>
{ return abs((m / gcd(m,n)) * n); }

いくら短いとはいえ、このようなコードをコピペして使いまわすのは不適切だ。このような基本的でよく使われる関数は、標準ライブラリに存在するべきなのだ。

[PDFは拡張せずに滅びるべき] N3846: Extending static_assert

C++11で追加されたstatic_assertは、必ず文字列リテラルを指定しなければならない。

// C++11のstatic_assertの例
static_assert( true, "This can't be possible!") ;

しかし、なぜ指定しなければならないのだろうか。単にコンパイル時assertを書きたいだけで、特に文字列を指定したくない時でも、たとえ空にせよ、文字列リテラルを指定しなければならないのだ。

さらに、現在のBOOST_STATIC_ASSERTの実装は、コンパイラーにstatic_assertが実装されている場合は、以下のようになる。

// BOOST_STATIC_ASSERTの実装
#define BOOST_STATIC_ASSERT(B) static_assert(B, #B)

これはつまり、以下のように書くと、

BOOST_STATIC_ASSERT(( sizeof(int) == 4 )) ;

以下のように展開される。

static_assert(( sizeof(int) == 4 ), "( sizeof(int) == 4 )") ;

多くのプログラマーにとって、static_assertに指定した式を文字列として読め、しかもそれがデフォルトとなっているのは、便利だ。

このような文字列リテラルを指定しないstatic_assert、デフォルトで式を文字列化するstatic_assertは、何年もの間、多数の人から、要望されてきた。

実際、BOOST_STATIC_ASSERTと同等のマクロは、実に大勢のものによって、再発明されてきた。これは、明らかに利用者がこのような機能を必要としている証拠である。

とはいえ、式を文字列化するというのは、ただでさえコンパイラーの実装が難しいC++では、とても難しいのだ。Phase of Translationをかける前の文字列でなければならない。あるいは、トークン列に分割したものを再び文字列化するか。

それ故、多くのコンパイラー屋は、式を文字列化するという機能をコア言語でサポートすることに難色を示している。「文字列リテラルを取らない文法を追加して、出力される文字列は実装依存とするならば反対はしないが、式を文字列化するというのは、C++コンパイラーの実装の都合上、とても難しい」という意見だ。これはプリプロセッサーの仕事だと主張するコンパイラー屋が多い。

一方、Cプリプロセッサーは醜悪であり、将来的には廃止されるべきであり、そのような機能に依存してはならないと江添は考える。

ところで、本当に式の文字列化は有益だろうか。実際にstatic_assertに引っかかったならば、ソースコードから問題のstatic_assertとその前後を確認するはずで、static_assertの式が文字列化されて、コンパイルエラーメッセージに含まれたところで、それほど意味はないのではないか。つまり、

#define STATIC_ASSERT(B) static_assert(B, #B)

このような実装と、

#define STATIC_ASSERT(B) static_assert(B, "ouch")

この実装で、現実的になにか違いはあるだろうか?

いやまて、そもそも、文字列以外の任意個の値を表示したい需要だってあるだろう。独自拡張を含めれば、様々な値がコンパイル時に取得できるのに、コンパイル時に値を表示できないのは残念すぎる。

static_assertがprintf風のフォーマットをサポートしてたら嬉しいって誰かが言ってた。

と、論文では収集がつかない意見の噴出を紹介している。

その上で、論文は、いくつかの文面案を提案している。

案1 (Daniel Krüglerの提案)

もし、文字列リテラルが与えられない場合は、結果のdiagnosticメッセージは、定数式のテキストである。

BOOST_STATIC_ASSERT相当の機能をコア言語で直接サポートする提案

案2 (Mike Millerの提案)

もし、文字列リテラルが与えられない場合は、結果のdiagnosticメッセージは、実装依存である。

すでにトークン列化されてるものを、再び文字列に戻したくねーよというコンパイラー屋の提案。

案4

コンマで区切って任意個の値を与え、それを人間が読める形で表示する提案

文面案の全訳は面倒なので、コードで示す。

// 案4の利用例
static_assert( sizeof(int) == 4,
    "Oops, the size of int is not 4! Use this:", sizeof(int),
    " Also check the size of long, just in case :D :", sizeof(long)
) ; 

これは・・・はて、どうだろう。

何にせよ、文字列を指定しないstatic_assertは欲しいところだ。

[PDFは簡単ではない!] N3847: Random Number Generation is Not Simple!

すでに提案中の、初心者にも使いやすい乱数ライブラリ、std::pick_a_numberに対する提案。

まず、pick_a_numberを関数テンプレートにし、浮動小数点数型も扱えるようにする。

// N3847提案のpick_a_number
#include <random>

int main()
{
    int a = std::pick_a_number( 1, 6 ) ;
    double b  = std::pick_a_nubmer( 1.0, 6.0 ) ;
}

また、関数オブジェクトとして呼ぶと乱数を返すクラスも提供する。これにより、<algorithm>に渡しやすくなる。

さらに、乱数を返すイテレーターも提供する。これにより、copy_nなどのアルゴリズムに渡せる。

クラスがテンプレートでないのは気になるところだ。

N3848: Working Draft, Technical Specification on C++ Extensions for Library Fundamentals

std::optionalのドラフト文面。

N3849: string_view: a non-owning reference to a string, revision 6

文字列をラップするクラス、string_viewの提案。

多くの場合、文字列を扱うとき、その文字列がどのように実装されているかは、どうでもいいことだ。std::stringかもしれないし、null終端されたcharの配列かもしれない。重要なのは、それが文字列として振る舞うことであって、実装方法の詳細ではない。そこで、様々な実装方法の文字列をラップして、共通の操作を提供するクラスが欲しい。

このような需要は極めて一般的なもので、GoogleとかBloombergとか、ChromiumとかLLVMなどといった企業やプロジェクトで、ほぼ同等機能のライブラリが、独立して再発明され続けている。それならば、標準ライブラリとして存在すべきだ。

string_viewは、具体的な文字列の実装を参照して、std::basic_string風のインターフェースで見るためのクラスであり、変更することはできない。変更できるようにすると、文字列リテラルでstring_viewを初期化することができなくなる。それに、文字列を変更するということは、往々にして、文字列の長さも変えなければならない。それには具体的な実装による処理が絡んでくる。そのため、文字列を変更するという需要はない。事実、LLVMでも、文字列を変更する版のライブラリを追加する需要は発生していない。

[PDFはやめてくれ頼む] N3850: Working Draft, Technical Specification for C++ Extensions for Parallelism

<algorithm>に並列実行版を付け加える提案のドラフト文面

この提案では、従来のアルゴリズムに、実行ポリシー(execution policy)を取るオーバーロードが追加される。

標準規格では、三つの実行ポリシーを定義している。すなわち、std::seq, std::par, std::vecであり、それぞれ、シーケンシャル実行ポリシー(sequential execution policy)、並列実行ポリシー(parallel execution policy)、ベクトル実行ポリシー(vector execution policy)である。既存のアルゴリズムは、すべてシーケンシャル実行ポリシーである。

並列実行ポリシーは、処理の実行単位が順序を問わず、未規定のスレッドで非シーケンシャルに実行される。そのため、スレッドローカルストレージなどは、実行の単位ごとに異なる可能性があるし、ロックなども慎重に使わなければ、実行単位の間でデッドロックを引き起こす。

ベクトル実行ポリシーは、処理が未規定のスレッドで実行されるし、またひとつのスレッドで実行された場合、非シーケンシャルである。ベクトル実行ポリシーはさらに制約が強く、実行単位の中では、一切のロックを行ってはならない。

// N3850の例
#include 

int main()
{
    std::vector v ;
    // vに値を入れる

    // 従来のsort、暗黙にシーケンシャル実行ポリシー
    std::sort( v.begin(), v.end() ) ;

    // 明示的にシーケンシャル実行ポリシー
    std::sort( std::seq, v.begin(), v.end() ) ;

    // 並列実行ポリシー
    std::sort( std::par, v.begin(), v.end() ) ;

    // ベクトル実行ポリシー
    std::sort( std::vec, v.begin(), v.end() ) ;
}

並列実行ポリシーや、ベクトル実行ポリシーが、どのように実装されるかは規定されていないし、それは規格が定めるところではない。

[多次元的に複雑なPDF] N3851: Multidimensional bounds, index and array_view

連続したメモリ配列に対して、多次元配列操作を提供する、array_viewライブラリの提案。Microsoftのライブラリ、C++ AMPを土台としている。

array_viewは、連続したメモリを参照して、あたかも多次元配列を操作しているかのようなインターフェースを提供する。

// N3851時点での提案の例
std::size_t M = 32 ;
std::size_t N = 64 ;

std::vector<float> v( M * N ) ;

std::array_view<float, 2> view{ { M, N }, v } ;


view[{ 3, 3 }] = 0 ;

また、array_viewは、bounds_iteratorにより、各要素に対して、一次元的なアクセスを提供している。

// N3851時点でのイテレーター
std::bounds_iterator<2> first = std::begin( view.bounds() ) ;
std::bounds_iterator<2> last = std::end( view.bounds() ) ;

float sum = 0.0 ;

std::for_each( first, last,
[]( std::index<2> index )
{
    sum += view[index] ;
}

string_viewとは違い、array_viewはmutableである。つまり、参照先を変更することができる。これは、文字列と多次元配列という違う概念による違いだ。LLVMでも、2011年2月に追加したimmutableなArrayRefに対して、mutable版のMutableArrayRefを追加したのが2013年1月。StringRefに対しては、いまだにMutableStringRefを追加する需要がない。

N3852: C++ FCD Comment Status

前回、各国から送られたNational Body CommentへのC++標準化委員会への返答。日本は一件も送っていない。

特に興味深いNBコメントの結果だけ紹介する。

CH2: スイスは、C++14はマイナーアップデートであり、ドラフトの質に影響するような大規模な変更をやめろと意見した。これは受け入れられた。その結果、optionalとdynarrayは、標準規格ではなく、TS(Technical Specification)という形で制定することになった。いずれは、標準規格にも取り入れられるだろう。

US15: アメリカ合衆国は、N3655により、すべてのtypetrait<...>::typeは、エイリアステンプレートを使って、typetrait_t<...>と書けるようになった。さっそく、規格の文面でも置換を行おうと意見した。これは採択された。

数値区切りは、一旦却下されたものの、各国から、入れろ、考えなおせというNBコメントが相次いだために、採択された。

// 数値区切りの例
int x = 1000'000'000 ;

ES8: グローバルなoperator delete[]に、第二引数にstd::size_t型で、ストレージのサイズを取るオーバーロードが追加された。これは、従来メンバー関数にはあったが、なぜかグローバルな解放関数にはなかったものだ。ストレージのサイズが渡されることで、一部のメモリアロケーターの実装の解放時の処理が、とても効率的になる。

GB4: 文面の変更により、ストレージ確保と例外がからむと、従来は余計にストレージが確保されて、もともとメモリーリークしていたコードが、さらにリークする可能性があるというイギリスの意見に対し、core issue 1786が作られた。

ES10, US8: [[deprecated]]は採択されたが、CDに入れ忘れているぞというスペインの意見に対し、N3394をCDに適用する対応がなされた。

US9: 現行ドラフトでは、実行時サイズ配列の添字が0と評価された場合、例外を投げるとしている。これは合法なC99のコードをC++14では実行時に失敗させてしまう。既存のC99コードには、添字0のコードが山ほどある。実際に、G++で実行時サイズ配列を実装して、既存のコードに試してみると、多くが壊れてしまった。添字が負数である場合はいいが、0の場合は認めるべきであるというアメリカ合衆国が意見した。これは採択された。core issue 1768

CH5: プリプロセッサーマクロ、__func__が関数の中ではないlambda式(名前空間スコープの中の初期化子の中のlambda式)の中で使えるかどうか、文面上疑問であるというスイスの意見。これは文面を修正することに決まった。

US13: 非volatileローカル変数をreturnするときは、常にムーブでいいだろうという米国の意見。これは採用された。

ES11: forward_as_tupleがconstexprではないというスペインの意見。constexprとなることに決まった。

GB9: C11では、忌まわしき危険なgetsが取り除かれた。まだC++はC99規格を参照しているとはいえ、getsに関しては、C++でも廃止すべきであるというイギリスの意見が採用された。

FI4: これは却下されたが面白かったので紹介。戻り値の型推定は、変換関数にも適用できる。

// 変換関数に関数の戻り値の型推定を適用する例
struct Zero
{
    operator auto() { return 0 ; }
} ;

int main()
{
    Zero zero ;
    int x = zero ;
}

N3853: Range-Based For-Loops: The Next Generation

range-based for loopは、従来のforに比べて、格段に使いやすくなった。

// 昔のforループ

void once_upon_a_time( std::vector<int> & range )
{
    for (   std::vector<int>::iterator first = range.begin(),
            std::vector<int>::iterator last = range.end() ;
            first != last ; ++first )
    {
        std::cout << *first << '\n' ;
    }
}

// 今のforループ

void and_now( std::vector<int> & range )
{
    for ( int elem : range )
    {
        std::cout << elem << '\n' ;
    }
}

なるほど、これはわかりやすくなった。しかし、要素の型を指定するのが面倒だ。そもそも、要素の型はコンパイル時に決定できるわけだ。重要なのは型ではない。すると、以下のように書ける。

// auto specifierの利用
for ( auto elem : range ) ;

なるほど、これは実にわかりやすい。ただし、これには問題がある。

// Range-based for loopとauto specifierの問題点

void f( std::vector< std::string > & range )
{
    for ( auto elem : range )
    {
        std::cout << elem << '\n' ;
    }
}

これは動くが、いちいちにstd::stringオブジェクトのコピーが発生してしまう。そして、従来のC++プログラマーは、このコードによってコピーが発生しているということを、見逃しやすい。これは問題だ。

では型名を書くかというと、それも問題なのだ。例えば以下のようなコードが問題になる。

// コピーが発生してしまうコード
void f( std::map< const int, int > & range )
{
    for ( std::pair< int, int > const & elem : range )
    {
    // ...
    }
}

これにはコピーが発生してしまう。なぜならば、rangeの要素は、std::pair< const int, int >だからだ。型の変換のためにコピーが発生してしまうのだ。

型名を明示的に指定するのは問題が多い。しかし、autoでもコピーが発生してしまう。ではどうすればいいのか。

"for ( auto & elem : range )"は、まだいくらかマシだ。しかし、これもvector<bool>のようなプロクシーイテレーターに対応できない問題がある。

// プロクシーに対応できない例
void f( std::vector<int> & v )
{
    for ( auto & elem : v )
    {
        std::cout << elem << '\n' ;
    }
}

int main()
{
    std::vector<int> non_proxy{ 1, 2, 3  } ;
    f( non_proxy ) ; // well-formed

    std::vector<bool> proxy{ true, true, true } ;
    f( proxy ) ; // ill-formed!
} 

vector<bool>は、規格上、だいぶ変わった実装をしなければならない。この実装はプロクシーと呼ばれてる技法が使われている。イテレーター一つ一つに対応する要素へのオブジェクトはない。そもそも、boolはたったの1ビットの情報で表現できるのだ。であれば、charの配列のようなストレージを用意しておき、その1bitづつに、要素一つを対応させればいいのだ。そして、イテレーターで変換を行う。

問題は、そういう場合に、bool一つ一つに対応するオブジェクトがないので、イテレーターはかなり不自然な挙動をする。もちろん、規格の要件通りなのだが、やはり不自然なことは不自然だ。

"for( auto const & elem : range )"は、ほとんどのプロクシー実装に対応できるが、これでは書き換えることができない。

実は、この問題を解決できる最高の方法があるのだ。"for ( auto && elem : range )"である。

auto &&は、どんなものにでも対応できる、万能の指定子なのだ。

しかし問題は、auto &&を使うには、プログラマーはrvalue referenceやauto specifierやTemplate Argument Deduction(とくにテンプレート名にrvalue referenceが用いられた場合の不思議な挙動)について精通していなければならない。それは初心者にはいかにも無理だ。

簡単に使えるように作られたはずの機能が、実際には簡単に使えないときている。これは簡単に使えるように、言語を拡張すべきだ。すなわち、新しい文法、"for ( elem : range )"の提案だ。

"for ( elem : range )"は、自動的に、"for ( auto && elem : range )"と書いたものと同様にみなされる。これにより、初心者も詳細を理解せずに使うことができる。文法上必要なゴミもなくなり、とてもわかりやすい。

N3854: Variable Templates For Type Traits

C++14では、エイリアステンプレートを用いて、従来のtype traitsの使いやすいラッパーを追加している。

// 新旧比較
std::add_pointer<int>::type old = nullptr ;
std::add_pointer_t<int> latest = nullptr ;

余計な、ネストされた型名、::typeがいらなくなるので、とても書きやすくなる。

type_traits_tは、エイリアステンプレートを用いたラッパーであり、以下のように書くことができる。

template < typename T >
add_pointer_t = std::add_pointer<T>::type ;

C++14には、変数テンプレートも追加されたので、これの値版を追加する提案。すなわち、

// 新旧比較
bool old = std::is_integer<int>::value ;
bool latest = std::is_integer_v<int> ;

::valueが必要なくなる。

この実装は、例えば以下のようになる。


template < typename T >
constexpr bool is_integer_v = is_integer<T>::value ;

これは入って当然の提案だ。

[PDFは忘却されるべき] N3856: Unforgetting standard functions min/max as constexpr

これは異例に短い論文。PDFである理由が全くわからない。

中身は、min/maxをconstexprにする提案だ。ついうっかり入れ忘れていたらしい。

岡山の某陶芸家がおお喜びする様が目に見えるようだ。

[PDFは改良の余地なし] N3857: Improvements to std::future<T> and Related APIs

非常に基礎的な機能しかなかった貧弱なfutureを大幅に改良する提案。便利な機能が追加される。この提案は、次にN3858と対になっている。

まず、futureの基本的な使い方をみてみよう。

// C++11のfuture
#include <future>

int main()
{
    auto f = std::async( [](){ return 123 ; } ) ;

    auto result = f.get() ;
} 

futureは、基本的にはこれだけしかできない。futureは、値をgetで取得する。そして、getは、値がfutureに対応するpromiseに設定されるまでブロックする。それだけだ。

then

futureに値が決定された後に、処理をしたいことはほとんどだろう。そもそも、値が決定されたら、自動的に処理をして欲しいはずだ。また、その処理は、再び非同期で実行されて欲しいかも知れない。すなわちfutureを返したい。C++11では、以下のように書かなければならない。

// C++11の例
#include <future>

int main()
{
    // まあ、これはいいか
    auto f1 = std::async( [](){ return 123 ; } ) ;
    auto r1 = f.get() ;// え、俺がやるの?

    // またかよ・・・
    auto f2 = std::async( [&](){ return r1 + 456 ; } ) ;
    auto r2 = f2.get() ; // で、また俺がやるの?
} 

たったの一回の後処理だけでこれなのだ。続けて何度も非同期な後処理をしたい場合、記述が煩雑になり面倒だ。

このような煩雑なコードは、thenにより簡略化できる。

// then
#include <future>

int main()
{
    auto f2 = std::async( []() { return 123 ; } )
                .then( []( auto f ){ return f.get() + 456 ; }
              )
    auto r2 = f2.get() ;   
} 

thenならば、futureの結果非同期に実行される後処理を、future.then(..).then(...).then(...)と続けて、簡潔に書ける。

unwrap

futureのネスト、すなわち、future<future<int>>>のようなことは、起こりうることである。では、ネストしたfutureを取り出すにはどうすればいいのか。getを使うとブロックしてしまうおそれがある。非同期に中身を取り出したい。しかし、futureから中身を取り出すために非同期処理を書くのは面倒だし、例外も面倒を見なければならない。非同期処理をした結果を得るのに非同期処理を自前で書くという、わけのわからないことをしなければならない。

unwrapは、そのような非同期のfutureの展開をしてくれるものだ。

// unwrapの例
#include <future>

int main()
{
    // outer_futureはstd::future< std::future< int > >
    auto outer_future = std::async( []{
        return std::async( [] {
            return 123 ;
        } ) ; // inner
    } ) ; // outer

    auto inner_future_proxy = outer_future.unwrap() ;

    inner_future_proxy.then([]( auto f ) {
        auto result = f.get() ;
    } ) ;
} 

is_ready

C++11のfutureには、getしかない。getは、まだ値が決定されていない場合、問答無用で待ちに入る。しかし、多くの場合、値が決定されているかどうかをブロックせずに確認だけしたいはずだ。こんな初歩的な機能が、C++11になかったのは、どうしようもないことなのだが、その機能が入る。is_readyだ。

// is_readyの例
#include <future>

void do_something_or_other( std::future<int> f )
{
    if ( f.is_ready() )
    {
        int value = f.get() ; // ブロックしない
    }
    else
    {
        // getはブロックするので、なにか別のことをする
    }
}

時間を指定する、wait_forやwait_untilはあったが、なぜこれはなかったのか。

when_any

複数のfutureのどれか一つでも完了した場合に値が決定するfutureを返す。

これには2バージョンあり、future<vector<future<T>>>を返すタイプと、future<tuple<future<T>>>を返すタイプがある、複数のfutureをイテレーターで渡すとvector版が、実引数で渡すとtuple版が返される

// when_anyの例
#include <future>

int main()
{
    std::future<int> futures[] = { 
        std::async( []{ return 1 ; },
        std::async( []{ return 2 ; },
        std::async( []{ return 3 ; }
    } ;

    // std::future< std::vector< std::future<int> > >
    auto vec_future = std::when_any( std::begin(futures), std::end(futures) ) ;
    // std::future< std::tuple< std::future<int>, std::future<int>, std::future<int> > >
    auto tuple_future = std::when_any( futures[0], futures[1], futures[2] ) ;

    vec_future.then([]{
        // どれかが完了している
    } ) ;
} 

when_all

複数のfutureのすべてが完了した時に完了するfutureを返す。

make_ready_future

futureを作るとき、すでに値が決定されていることが、しばしばある。しかし、値を設定済みのfutureを作るのは、C++11では意外と面倒だ。まず、promiseを作り、そのpromiseに値をセットして、そのpromiseからfutureを得なければならない。

// 値をセット済みのfutureを作る
template <typename T >
std::future< typename std::decay_t<T> > make_ready_future( T && value )
{
    std::promise< typename std::decay<T>::type > p ;
    p.set_value( std::forward<T>( value ) ) ;
    return p.get_future() ;
}

こんな基礎的なことを、わざわざ自前で書きたくない。間違いの元だ。最初からこれが標準ライブラリにあればよい。

[PDFを継続する必要はない] N3858: Resumable Functions

Resumable Functionの提案。

Resumable Functionとは、ブロックする実行を途中で中断して、関数の呼び出し元に、制御を返し、後で自動的に実行が再開されて、結果を得ることができる関数だ。futureにメンバー関数thenを付け加えるのもいいのだが、resumable functionがコア言語でサポートされていると、非同期コードが、とても簡潔に書けるようになる。

future.thenを使うと以下のように書かなければならないコードが、

// future.thenの例
future<int> f(shared_ptr<stream> str)
{
    shared_ptr<vector<char>> buf = ...;
    return str->read(512, buf)
        .then([](future<int> op)
        // lambda 1
            {
                return op.get() + 11;
            });
}

future<void> g()
{
    shared_ptr<stream> s = ...;
    return f(s).then([s](future<int> op)
        {
            s->close();
        });
}

以下のように簡潔に書けるようになる。

// resumable functionの例
future<int> f(stream str) resumable
{
    shared_ptr<vector<char>> buf = ...;
    int count = await str.read(512, buf);
    return count + 11;
}

future<void> g() resumable
{
    stream s = ...;
    int pls11 = await f(s);
    s.close();
}

非同期コードを書くときは、同期コードをまず書いてから、それを非同期コードに直すことも多いので、ほぼ同期コードと同じように書けるコア言語によるresumable functionのサポートは、コードの記述をとても簡単にする。

resumable functionの文法と機能について簡単に解説すると、以下のようになる。

resumable functionの宣言は、かならずresumable指定子を使わなければならない。resumable指定子とは、resumableというキーワードだ。

// resumableキーワード
std::future<int> f() resumable ;
[]() resumable {} ;

resumable指定子の位置は、関数とメンバー関数の場合、リファレンス修飾子の後、例外指定の前だ。

// 関数のresumable指定子の位置
struct S
{
    std::future<int> f() & resumable noexcept ;
} ;

lambda式の場合、mutableの後、例外指定の前になる

// lambda式のresumable指定子の位置
[]() mutable resumable noexcept -> std::future<int>{ return 0 ; }

もし、resumable指定子のあるlambda式で、戻り値の型が省略された場合、戻り値の型は、Tをreturn文から型推定された型とすると、std::future<T>になる。

// lambda式かつresumable functionの戻り値の型推定
// 戻り値の型はstd::future<int>
[]() resumable { return 0 ; }

resumable functionには、いくつかの制約がある。大きな制約を抜き出すと、

  • resumable functionの戻り値の型は、std::future<T>か、std::shared_future<T>でなければならない。Tがvoid型のときは、値を返さないresumable functionとして認識される。
  • C言語からある可変引数(...)は使えない。Variadic Templatesの関数パラメーターパックは使える。

resumable functionの関数の本体では、await演算子が使える。これも新しいキーワードで、文法上、式になる。

await expr

したがって、条件を満たす式ならば、どこにでも使える。awaitを使った時点で、関数の実行は中断され、その時点で呼び出し元に処理が戻る。そして、await演算子のオペランドが終了した時点で、resumable関数の実行が再開される。

//awaitの例
std::future<void> f() resumable
{
    // 事前の処理
    int r1 =  await std::async( []{ return 0 ; } ) ;
    // 事後の処理
    int r2 = await std::async) [] { return 0 ; } ) ;
    // さらに処理

    return ;
}

await演算子の特徴で、特に興味深いものを抜き出すと、

  • await演算子は、resumable functionの中か、decltype式の中でしか使えない。
  • await演算子のオペランドの式を評価した型は、future<T>かshared_future<T>か、あるいは、このどちらかの型に暗黙に変換可能でなければならない
  • await演算子は、例外ハンドラーの中では使えない。
  • mutexのロックを取得している状態でawait演算子を実行してはならない。
  • await演算子を評価した結果の型は、futureかshared_futureをgetした結果の型になる。もし、型がvoid型の場合、await演算子は他の式の中では使えない。

論文では、resumable functionの実装方法の例についても言及している。

とても簡単な実装は、サイドスタックと呼ばれる方法だ。これは、resumable functionが発動する際に、専用のスタック用のメモリーを確保し、resumable functionに入る前と後で、スタックポインターのすげかえを行う。これにより、ローカル関数を始めとしたスタックに依存するものが、問題なく動くようになる。ただし、スタック用のメモリは、ある程度の大きさの連続したメモリ空間を必要とするため、効率が悪い。

より効率的な実装としては、メモリをヒープ上に動的に確保して、参照カウンターで管理する方法がある。しかし、この方法は、実装が難しい。

論文では、将来の拡張の可能性についても言及している。

まず、汎用化だ。futureやshared_future以外の型も、メンバー関数getを持つとか、thenを持つとか、is_readyを持つなどすれば、認めるという案だ。これにより、汎用的に書ける。

そして、ジェネレーターだ。C#やPythonではすでに実用化されているパラダイムだが、値の集合を一つ一つ遅延して計算したいときなどに、ジェネレーターを使うと、とても自然に書ける。このために、yieldというキーワードを導入し、yieldが実行されるたびに関数から処理を戻すような機能を提供する。

ジェネレーターは、非同期やスレッドとは関係がないが、とてもおもしろくて便利なパラダイムだ。ぜひともジェネレーターは、将来、議論されて欲しい。

[空間の間に消えてほしいPDF] N3859: Transactional Memory Support for C++

トランザクショナルメモリー(Transactional Memory)の提案。

トランザクショナルメモリーとは、並列実行における複数のストレージへの排他的なアクセスを、より簡単に行うための機能だ。

複数のスレッドから、複数のストレージに書き込む場合は、mutexなどの方法で、排他的なロックをかけなければならない。

// mutexの例
int x = 0 ;
int y = 0 ;
// x, yにアクセスする際は、かならずmをロックすること
std::mutex m ;

void f()
{
    {
        std::lock_guard< std::mutex > lock(m) ;

        ++x ;
        ++y ;
    }
}

しかし、このような明示的にロックするコードは、書きにくい。わざわざロック、アンロックしなければならないし、mutexオブジェクトの管理も面倒だ。もっと簡単に書けないものか。

そこで、Transactional Memoryの出番だ。これはコア言語の文法として提供される機能なので、とても簡単に使えるようになっている。

// N3859提案のTransactional Memoryの例
int x = 0 ;
int y = 0 ;

void f()
{
    synchronized
    {
        ++x ;
        ++y ;
    }
}

Transactional Memoryを使えば、自前でmutexオブジェクトを管理せずに、とても簡単に複数のオブジェクトへの排他的なアクセスを書けるようになる。

これは同期ブロック(synchronized block)と呼ばれている。その文法は、キーワードsynchronizedに続けてブロック文を書く。すべてのスレッドのすべての同期ブロックは同期する。つまり、同期ブロックの評価は、あたかもひとつのスレッドの中で逐次実行したかのように振る舞う。つまり、正しく同期ブロックの中から読み書きすれば、複数のスレッドからであっても、競合は一切起こらない。

Transactional Memoryには、もうひとつ。アトミックブロック(Atomic Block)というものがある。これには、三種類ある。

// N3859提案のAtomic Block三種類
atomic noexcept { /* ... */ }
atomic commit_except { /* ... */ }
atomic cancel_except { /* ... */ }

アトミックブロックの文法は、キーワードatomicに続けて、noexcept/commit_except/cancel_exceptのいずれかのキーワードを書き、その後にブロック文を書く。

atomic noexceptは、アトミックブロックの中から外に例外を投げないことをユーザーが保証する。

// atomic noexcept
atomic noexcept
{
    try
    {
        // ...
    }
    catch( ... )
    {
        // 絶対に外に例外を投げないように握りつぶす
    }
}

atomic commit_exceptは、アトミックブロックから例外によって抜けだした際に、トランザクションをコミットして、例外を投げる。つまり、それまでの副作用をブロックの外から観測できるようにする。

// atomic commit_except
int x = 0 ;
int y = 0 ;

void f()
{
    try
    {
        atomic commit_except
        {
            ++x ;
            throw 0 ;
            ++y ;
        }
    } catch( ... ) { }

    // この時点で、他のスレッドを考慮に入れなければ
    // xはインクリメントされている
    // yは初期値のまま
}

atomic cancel_exceptは、アトミックブロックから例外によって抜けだした際に、それがTransaction-safeな例外であれば、トランザクションをキャンセルして、例外を投げる。つまり、それまでの副作用をなかったことにする。

// atomic cancel_except
int x = 0 ;
int y = 0 ;

void f()
{
    try
    {
        atomic cancel_except
        {
            ++x ;
            throw 0 ;
            ++y ;
        }
    } catch( ... ) { }

    // この時点で、他のスレッドを考慮に入れなければ
    // xは初期値のまま
    // yは初期値のまま
}

transaction-safeな例外というのは、N3859提案の段階では、bad_alloc, bad_array_length, bad_array_new)length, bad_cast , bad_typeid , スカラー型となっている。議論の上で、この制限を緩和することも考えているそうだ。

アトミックブロックの中の副作用は、アトミックブロックを抜けた際に、一斉に観測できるようになる。つまり、

// 副作用は一斉に見えるか見えないか
int x = 0 ;
int y = 0 ;

void f()
{
    atomic noexcept
    {
        ++x ;
        // #1
        ++y ;
    }
    // #2
}

#1の時点では、アトミックブロックの中では、xはインクリメントされているようにみえるが、他のスレッドからは、xは初期値のままにみえる。

#2で、すべてのスレッドから、xとyが一斉にインクリメントされたように見える。この点では、同期ブロックもアトミックブロックも変わらない。また、アトミックブロックも、観測できる範囲では、同期ブロックと同じく、順序だって評価されているように見える。

では、アトミックブロックは、同期ブロックとどう違うのか。同期ブロックというのは、単なるプログラム全体で単一のmutexを共有するような想定だが、アトミックブロックというのは、何らかのハードウェア、ソフトウェアによる効率的なトランザクショナルメモリーの実装が行われることが期待されている。もちろん、規格上、どのように実装されるかという詳細は規定していないのだが。

また、規格ではTransaction-safeという概念を提唱し、Transactional Memoryのブロック内で行える処理に制限を設けている。また、関数をtransaction-safeとtransaction-unsafeに分けている。これらはキーワードで明示的に指定することもできる。既存のSTLコンテナーなどの標準ライブラリはtransaction-safeで使えるべきで、対応すべきだという意見も提示している。

[読みづらいPDF] N3861: Transactional Memory (TM) Meeting Minutes 2013/09/09-2014/01/20

トランザクショナルメモリーに関する会議の議事録

[PDF廃止に向けて] N3862: Towards a Transaction-safe C++ Standard Library: std::list

GCC 4.9に実装されたTransactional Memoryの実験的実装を使い、libstdc++のstd::listを、実際にtransaction-safeにしてみる実験。変更は最小限ですんだそうだ。

そのコードはGitHubに上がっている。

mfs409/tm_stl: A scratchpad for working on making some of the C++11 STL code from gcc 4.9 transaction-safe

残りの論文も、追って解説する。

ドワンゴ広告

この記事はドワンゴの勤務時間中に書かれた。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

アマゾンの欲しい物リストで送られてきたものと、付随した変なもの

先日、アマゾンで江添のほしい物リストを公開した。以前から、アマゾンのウィッシュリストは公開してみたかったのだが、一人暮らしの身では、なにか面白いものが送られてきても、反応に困るという問題があった。今住んでいるシェアハウスならば、大抵のものは処理できる。必要な人間がいるだろうし、あるいはいい笑いの種になる。以前、実際にかの悪名高い天竜川の洗い砂が送られてきたこともあったらしいが、それも土地を持っている住人の庭にまくという方法で、問題なく処分した。

そういうわけで、様々なジャンルからほしい物、面白いが金を出して買う程でもないものをぶち込んだお気に入りリストを公開した。

まず送られてきたのは、 ガベージコレクションのアルゴリズムと実装だ。そして、私はリストに追加していなかったが、注文に付け加える形で送られてきたのが、ECMA-262 Edition 5.1を読むだ。GC本は前から欲しかった本だ。ECMAScriptの規格書の方は、私はJavaScriptの規格ならば、C++ほど読み込んではいないものの、原文を読めるので、翻訳は必要ない。翻訳するということは、翻訳作業に起因する問題が生じるので、なるべくやりたくないことだ。ECMAScript規格翻訳本をどうするかは、今検討中だ。おそらく、誰か人に譲るのがいいのだろうが、しかし、やはり原文を読むべきではないか。

次に送られてきたのは、 T-fal 電気ケトル ジャスティン プラス カカオブラック 1.2L KO340870だ。電気ケトルは、すぐに湯を沸かせる便利な文明の利器で、大変重宝している。まずはお茶をいれるためのお湯を沸かすのに使った。

問題は・・・電気ケトルに付随して送られてきたものだ。

なにやら赤い布切れが入っている。これは・・・ 【日本製】 褌(ふんどし) 赤色無地だ。赤い越中ふんどしが入っていた。さて・・・コレは一体・・・どうするべきか。

筆者は日本人であるが、いまだにふんどしというものをはいたことはない。筆者は服には機能性を求めるので、しめるのにひと手間かかるふんどしを履くことはなかった。しかも、赤いふんどしというのは、日常に使うには不向きだ。そもそも筆者は越中ふんどしのしめ方を知らない。幸い、越中ふんどしは、褌の中でも締めやすい方ではある。これが六尺褌だったら、面倒なことになっていたはずだ。

さて、褌だけしめて洋服というのもおかしい。この機会に、作務衣や和服、足袋、雪駄のたぐいも江添のほしい物リストに追加することにした。

さて、ふんどしだけかと思ったら、まだなにか小さな小箱が入っていた。これは・・・ ISHOKUYA(衣飾屋) ユニーク タイピン タイ止め タイバー 纏 まといだ。

さて、ユニークという言葉の使い方が間違っている。なぜか唐傘のような意匠のタイピンだ。しかし、私はふだんネクタイという現代版の奴隷の鎖で首枷をする習慣はない。奴隷が鎖を自慢することが愚かであるように、私も鎖の自慢はしない。いわんや鎖を固定するにおいてをや。

そして、同封の紙にかかれていたメッセージは、

就職おめでとうございます!ビジネスマンたるもの見えない所の身なりもきっちりしないといけませんね!

なるほど、真のビジネスマンは赤ふんに唐傘ネクタイピンを装備するものなのだな。いやぁ、社会人経験の浅い筆者には、社会人の常識というものが欠けていたものと見える。これからはしっかりと社会人の常識を身に着けねばならない。ただし、聞くところによると、この社会人の常識というものは、実行環境ごとの互換性が一切ないシロモノらしいのだが。

江添のほしい物リストは、まだまだなにか面白いものを追加する予定だ。

2014-02-13

ドワンゴに入社した

そう。タイトル通りだ。筆者、江添亮はドワンゴに雇用された。一体、どのような経緯でドワンゴに入社するに至ったのか。また、どんな仕事をしているのか。それを説明するには、時系列を追って書いたほうがいいだろう。

2013年8月21日

ふとみると、以下のようなサブジェクトのメールが届いていた。

【ご相談】ドワンゴ主催の C++11, 14 に関する勉強会にスピーカーとしてご参加頂けないでしょうか

C++11? C++14? なんと、日本にC++14などという単語を知っている企業があったのか。しかし・・・ドワンゴ?

SPAMだろうか。いや、こんなにピンポイントなSPAMがあるわけがない。

それにしても解せないメールだ。ドワンゴといえば、もちろん、あの有名なニコニコ動画の企業だ。ニコニコ動画と言えばWebサイトだ。ニコニコ動画やその関連サービスの開発にC++を使っているのだろうか。いやまて、たしか子会社にチュンソフト(現スパイク・チュンソフト)がいたはずだ。ゲームならばC++はありえる。しかし、今の日本のゲーム業界は、とてもC++11/14の勉強会を開ける状況とも思えないのだが、一体どういうことだ。いや、いくら子会社とはいえ、ドワンゴの名前で来るだろうか。あるいは、単に宣伝目的で勉強会を主催したいのだろうか。

ともかく、C++14であれば、ドラフト規格はもうほとんど固まっている。今回は、マイナーアップデートとはいえ、C++03と違って、コア言語にも小粒な変更をいくつも含んでいる。C++14で追加されたコア言語機能の紹介をすればよさそうだ。しかし、釣りではあるまいな。

2013年11月14日

そうして、歌舞伎座.tech#2が開催された。

当日のスライド資料:C++14の新機能

当日のTwitterのまとめ:歌舞伎座.tech#2「11/14なのでC++11/14のお話」ハッシュタグ#kbkz_tech保管庫 - Togetterまとめ

技術評論社の記事:第7回 エンジニアなら,一生学び続けるのは当たり前――社内勉強会を重視する社風から生まれたドワンゴ主催「歌舞伎座.tech」:IT勉強会を開催するボクらの理由|gihyo.jp … 技術評論社

勉強会の告知では、平日の夜なのにも関わらず、100人枠が一日で埋まっていた。さすが東京といったところか。

この勉強会のドワンゴ社員の発表によれば、ドワンゴのバックエンドにはC++が使われているという。それは知らなかった。

さて、勉強会の次の日に、懇親会という形で食事に誘われた。その食事の席で、話の流れで、私がドワンゴで働く可能性についての話題に向かっていった。

しかし、働くといっても、今の私は、C++の標準規格という、とても狭い範囲のみを深く学びすぎてしまった。特に、この数年間、C++の参考書の執筆をしていたのは影響が大きい。この数年、私はいかに簡潔なコードで、C++のある特定の機能の説明をするかということのみに注力してしまった。残念ながら、今仕事用のコードを書くといっても、未経験者とそれほど変わらない程度の能力しかない。それに、私は不自由なソフトウェアを使いたくないし、書きたくない。

あるいは、C++の教育を行うというのも、企業に雇われる形では難しい。というのも、たいていの企業に雇われた教育者というのは、単に社内の閉鎖的な環境に引きこもり、表に出てこない。私は、表に出せないC++の教育などしたくはない。というのは、そのような企業内の教育者は、C++標準化委員会に存在しないからだ。C++の規格を真面目に理解しようとすれば、必ず表に出てきて、議論に参加しなければならないし、いずれC++標準化委員会に籍をおくことになる。

それに、C++の教育を公にできれば、ドワンゴ社内にとらわれずに、皆がC++を学ぶことができ、日本のC++プログラマーの能力の向上にもつながる。それは、やがてはより優秀なC++プログラマーが労働市場に存在することにもなる。

そもそも、私が常に変わり続けるC++の標準規格の変更についていけるのは、圧倒的に自由な時間があるからだ。もし、雇われた後もC++の規格についていくためには、私はいつでも好きなときに好きなだけ、C++WGのドラフト規格や論文を読めなければならない。さもなければ、私は雇われた時のC++規格から先にはついていけない。

しかし、ドワンゴによれば、それでいいのだという。さらにドワンゴは、会社としてできることをするという。たとえば、C++標準化委員会の委員(現時点で、筆者はエキスパートメンバー、委員はスポンサーが必要)にしてくれるとか、C++の国際会議に出してくれるなどという話も出た。

私の仕事は、ブログを書くことや、C++の講演会をすることといった、C++の啓蒙活動になるという。

にわかには信じがたい話だ。しかも、いま話している場所は、非公式の食事の席である。とにかく、来月12月に、もう一度、講師として来てくれということで、その日は終わった。

2013年12月18日

さて、前回の勉強会から一ヶ月後に、また講師として呼ばれた。今回は、社内の講習会で、C++の歴史について話してくれということだった。ドワンゴの川上会長も見に来るのだという。幸い、私はC++の歴史にも興味があり、特にプログラミングの魔導書 ~Programmers’ Grimoire~ vol.1を書くときにも相当に調べたので、好都合だ。また、この機会に、C++WG JPの設立当初の人に、当時の話を取材した。

その結果書いたのが、C++の歴史というスライド資料だ。

さて、当日の私は、わざわざ外部から講師を招くぐらいだから、ドワンゴ社員の数十人もみるのだろうと考えていた。しかし、何故か当日通されたのは、机を囲んで椅子が七席あるだけの小規模な会議室。そこに、今の私の上司が座り、ドワンゴ社員が数名座り、そして川上会長が来て、いわゆる「社内講習会」が始まった。

C++の成り立ちから、C++の標準規格の制定方法までを解説し、そして、間に少し挟んだC++の機能解説を始めた。

川上会長がテンプレートに興味を示したので、テンプレートの機能を解説した。しかし、どこまで詳細に解説してよいものか。事前に、川上会長はC言語は分かると聞いているのだが、どこまでC++の詳細を理解してくれるだろうか。

どうやら、川上会長の興味は、テンプレートがどのように実装されるのかという低級な方向に向いているようだった。そこで話がコンパイラーの実装に進み始めた。ただし、なぜか川上会長の興味が低級層にあるためか、話の方向がどんどん低級よりになっていった。

江添「・・・ですから、オーバーロード関数やテンプレートといった、同じ名前で、異なるコードが生成される機能を、古典的なコンパイラーとリンカーの上に実装するには・・・」
川上会長「ああ、シンボル名に埋め込む必要があるわけか」
江添(ほう・・・)

どうやら、川上会長は名前マングリングの必要性をすでに理解しているようだ。それならば話は早い。何も遠慮するには及ばない。名前マングリングの必要性がパッと出てくるぐらいならば、他の詳細も全力を出して解説しても理解できるだろう。

しかし、テンプレートにODRの例外が認められているというところで、説明が停滞した。この部分は、かなり複雑な歴史と、コンパイラーの実装方法の経緯と進歩が関わっているので、口頭で説明するのはとても難しい。結局、この部分を理解してもらえたかどうか自信がない。

具体的な説明は、魔導書Vol.1にも書いたのだが、いい機会なので、改めて以下に書いておいた。

本の虫: テンプレートの実体化の実装方法とODR違反について

さて、数人しか聴衆のいない「講習会」が終わったあとで、別室に通されて一時間ほど話した。

私の仕事は、「C++の啓蒙」だという。このブログを書く、C++の勉強会を開くなどといった、C++の啓蒙活動だけすればいいという。

江添「私は不自由なソフトウェアを使いたくないのですが」
ドワンゴ「いいですよ、私物のPCで作業してもらえれば」
江添「私は不自由なソフトウェアを書きたくないのですが」
ドワンゴ「いいですよ、社内外へのC++の啓蒙だけすれば」

そして、C++の国際会議に出してくれるなどといった話も出た。

たしかに、もし本当にこの仕事内容であれば、私は毎日出社する必要はない。ブログは自宅でも書ける。もし本当にこの仕事内容であるとするならば、そのような極端な言葉が出てきても不思議ではないのだが、果たして。

内定通知書が届けば、ドワンゴに内定したことは公にしてもいいという話ではあった。しかし、筆者は、ドワンゴに実際に入社して、一週間ほど働いてみてから、公開しようと考えた。というのも、この口頭で交わした条件が、実際に守られるかどうかは、実際に働いてみるまでわからないのだから。

そうして、引越と引越し先の環境整備をしているうちに、とうとう、ドワンゴの入社日がやってきた。

2014年2月3日

歌舞伎座タワーに入っているドワンゴ本社に行き、必要な書類に署名をし、社内の出退勤記録などの社員管理のシステムをわずかに説明された後、私に割り当てられた机に案内されて、そして放置された。その日は少しだけC++WGの論文を読み進め、社員管理のシステムの操作方法を覚えるなどして終わった。

2014年2月4日

ドワンゴの周辺でまともな飯屋がないので、弁当を作ってから出社した。この日も論文と環境整備だけで終わった。

2014年2月5日

この日は、結構論文を読んだ。昼に食事をしながらカタンをした。

2014年2月6日

今日は、ためしに朝早く出てくることにした。なんと、午前10時に出社した。ほとんど人がいなかった。ドワンゴでは、午前10時というのは早朝なのだ。

論文を読み進める。

2014年2月7日

今日は、三叉の電源コードが欲しかったので、安いジャンク品を求めに朝から秋葉原に行った。ついでに、秋葉原を散策してみた。

ドワンゴには昼過ぎに出社した。

また論文を読む

ドワンゴの労働環境

ドワンゴの正社員には、真の裁量労働制が行われている。コアタイムはない。会議などであらかじめ予定が決まっている時以外は、何時に出社してもいいし、何時に帰ってもいい。たったの一時間会社にいるだけでも、その日は出社したとみなされる。

また、社内の労働も、相当に裁量がある。社内でゲームをしていたり寝ていたりする人までいる。

さて、そのような裁量が与えられた環境で、果たして人は真面目に働くのだろうか。これは、プログラミングという仕事においては、どうやらうまく動くようだ。

そもそも、毎日同じ時間に集合して労働するという集約労働は、単調作業には向いているかも知れないが、プログラミングという作業には向いていない。プログラミングには集中力が必要であり、その集中力は毎日決まった時間に発揮できるわけではない。そして、最高の集中状態を保てる時間というのは、それほど長くはない。

そもそも、本物のプログラマーは、余暇にも趣味のプログラミングを行うものである。本物のプログラマーが働きやすい環境を整えてやれば、自然に働くものだ。

ただし、プログラマーに真の裁量性を与えると、自然と昼過ぎに出社して夜遅くまで働く形になってしまうようだ。ドワンゴでは、11時から昼過ぎにかけて出社し、午後9時頃まで働く人が多い。

さて、こうして一週間出社したが、どうやら事前の話の条件は守られているようだ。

そもそも、今はちょうど2014-01 pre-Issaquah mailingが公開されたばかりだ。このブログで恒例の簡易レビューを書かなければならないが、今回は、50本以上もの論文があり、多くがC++17への提案論文なので、相当に時間がかかる。また、仕事としてやる以上、いつもより丁寧に読みたいし、「私はコア言語が専門だからライブラリは知らない」というわけにもいかない。今まで読み飛ばしていたライブラリの論文も読んでいるので、今回の簡易レビューはかなり時間がかかる。

そういうわけで、ブログを書くという話で入社して一週間、まだC++の記事は何も書いていない。たまたまC++WGの論文集が出る時期にあたったからだが、私はひたすら論文を読んで簡易レビューを書き進めているだけなので、単に机に座っているところだけを見ると、仕事をしているのかサボっているのかさっぱりわからないように見えるはずだ。

ところで、ドワンゴ社内の環境は、ブログ執筆のためには、自宅に劣らないほどよい。というより、今の自宅は、まだまともな椅子と机とディスプレイを揃えていないので、ドワンゴ社内に劣っている。早く自宅も快適な環境にしなければならない。

仕事

筆者のドワンゴにおける仕事は、C++の啓蒙活動だ。

具体的には、ブログを書くこと、C++の講演会をすること、ドワンゴの宣伝、そして、最大の目標が、「日本のC++の教育を再び活性化させること」だ。

この最大の目標をどうしたものか。今や、教育機関に、C++標準化委員会に籍をおいている者がいない。C++の規格に詳しいものが現状でいない以上、C++の教育など絶望的だ。教育を活性化させるには、C++プログラマーの働き口を増やさなければならない。それはドワンゴ一社のみでは難しいので、日本の企業全体を巻き込まなければならない。しかし、それも難しいのだ。現状の日本では、C++が使われている職場では、C++未経験者を雇って、やっつけ仕事をさせることが常態化している。C++の文法がわからず、何時間もコンパイラー(それも不自由で規格違反だらけのコンパイラー)にあてずっぽうで適当なコードを通そうとやっきになっている。残念の極みである。

日本では、標準規格の価値が理解されておらず、閉鎖的な独自仕様で囲い込んだ挙句、標準規格を作った海外勢に押されて負けるという歴史を繰り返している。ああ、いつになったら学ぶのか。

この現状を、どうやって変えていけばいいのだろうか。目標があまりにも巨大で漠然としていて、どこから手を付けていいのかわからない。とにかく、できることをしなければなるまい。さしあたっては、C++の解説記事を書くことと、C++の講演会を開くことにする。

また、このブログ記事を使いやすくするために、近々GitHub Pagesでも同一内容を公開しようと思う。

ドワンゴ広告

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0

2014-02-10

東京は住みにくい

さて、東京に引っ越して数週間たった。結論から言うと、東京は住みにくい。

東京に来てまず気がついたのは、メシのまずさだ。どの飯屋に入っても、京都より数百円高い上に、クソまずい。私は未だに、東京でまともなメシ屋を発見したことがない。それは、何万円も払うような店ならば、少しは違うのかも知れないが、私はそんなごちそうを食べたいのではない。普通のメシを普通の値段で食べたいのだ。東京の飯屋は、800円や1000円も取る割に、どうやったらこんなにまずく作れるのだと疑問に思うほどまずいメシしか出てこない。

色々と考えた挙句、結局、東京には出汁という文化がないのではないかという結論に達した。東京には油か醤油の薄め液しかないのだ。

とくに、うどんとそばが最悪だ。そばはまだともかく、うどんはつゆの良し悪しで味が大きく左右されるというのに、東京の飯屋のめんつゆは、醤油の薄め液のようなものしか出てこない。パスタにケチャップをかけて食うのじゃあるまいし、一体この文化のなさはなんだろう。めんつゆというのは、極端に言えば出汁だけでいいのだ。醤油などいらないのだ。

ラーメンもマズい。思えば、京都はラーメンが美味かった。私は歳のせいか、脂っこいものはあまり食べないのだが、それでも、京都でたまにラーメンを食べると美味しく感じた。しかし、この東京では、まともなラーメンを食べることができない。

結局、東京では一見さんだけを相手に商売できるので、マズい飯屋が自然に淘汰されないのだろう。そして、文化のなさにより、まともなメシをつくる誇りすらない。

そして、売っている食材も、あまりよろしくない。野菜や豆腐のようなものは、かなり地域性がでるものだ。東京で売っている食材はマズい。

なるほど、京都に住んでいた時、就職したが東京の本社で働かなければならなかったので、やめて京都でぶらぶらしているという人間が何人かいたのは、このせいでもあるのだろう。

東京はモノがあふれていて、何でも手に入るので便利ではあるのだが、普段食べるまともな食事という点では、極めて劣っている。

電車の問題は、いまさら私が書くまでもあるまい。

VLCメディアプレイヤーをインストールするとDellの保証が無効になる

Installing VLC Media Player voids your speaker warranty! - Laptop Audio Forum - Laptop - Dell Community

Dellのフォーラムで、ユーザーが、もし詐欺商品を売りつけるDellの貧弱で欠陥ラップトップで音量を最大にして音を再生すると、内蔵スピーカーが壊れ、しかも、VLC media playerがインストールされると、保証が無効になったという報告を上げている。

以下、粗悪な欠陥品を売りつけるDellの詐欺に騙された無知な顧客のコメント

Dell技術サポートは、有名なVLC Media PlayerがDellのラップトップにインストールされていた場合、壊れたスピーカーの保証を無効にするぞ。それから、KMPlayerがラップトップにインストールされてるとサポートを拒否されるという報告もある。ラップトップの他の部分の保証は有効らしいが。

気をつけろ。使っていたかどうかにかかわらず、特定のプレイヤーをインストールしていただけで保証を拒否される。技術サポートに連絡する前にプレイヤーを消して、Windows Media Playerだけ残しておけ。

VLCは他のプレイヤーよりも音量を大きくする機能がある。どうやらVLCにはハードクリッピングを発生させて、小さなスピーカーを壊すらしい機能があるらしいのだ。DellはVLCをテストして、数時間のVLCの仕様により、スピーカーが壊れることを確認したそうだ。また、HPもVLCによる故障は保証外だと言っている。

これは、Dellのラップトップの設計上の欠陥である。Dellのラップトップでは、サウンドチップが、内蔵スピーカーの許容入力以上の出力を送ってしまっているのだ。

Installing VLC Media Player voids your speaker warranty | Hacker News

VLCの主要開発者として、この我々はこの問題を昔から知っている。これは単に、Dellがクソな部品を使っていて、他人のせいにしているだけだ。奴らにはまともな議論が通用しない。ちょっと説明してやろう。

この件では、VLCは単にWindowsのAPI(DirectSound)を使っているだけで、Windowsカーネルに16bit符号付き整数を送っているだけだ。

VLCには、デコードされた時以上に入力を増幅することができる。これはリプレイゲインとか壊れたコーデックとか録音がひどかったファイルとか、ポストプロセスによる増幅で、サチュレーションが発生するのと同じだ。

これは、単にmp3ファイルをAudacityに突っ込んで音量を上げ、WMPで再生するのと同じことだし、DirectShowフィルターで、コーデック出力の後に増幅するのと同じことだ。例えば、だいぶながいこと、VLCのac3とmp3デコーダーは、リファレンス出力に比べて、音が小さかった(-6dB)

これにより、音の強弱が失われたり、音が割れたりするが、ハードウェアを壊すことはない。

VLCはスピーカーを壊すように出力を変更することはないし、そもそも不可能だ。VLCは「公式」のプラットフォームAPIを使っているだけのソフトウェアだ。

この問題の原因は、Dellのサウンドカードが、Dellのスピーカーが耐えられないほどの出力(増幅の二乗)を出せてしまうためだ。問題のサウンドカードの最大出力は10Wだが、問題のスピーカーが許容できる入力はたったの6Wで、BIOSもドライバーも出力をブロックしない。

そして、VLCが多くのコンピューターに入っている現状で、VLCのせいにするのが簡単だったというだけだ。「相関関係は因果関係を意味しない」という概念は、貧弱なDellのサポートの頭には複雑すぎて理解できないことらしい。

たぶん、Dellはメタル音楽の再生をやめるように告知して、セリーヌ・ディオンの再生のみを許可するべきだろう。メタルは音割れが頻繁に発生するからな・・・

追記:やつらはこの問題を修正するためのBIOSアップデートまで提供してるんだぞ。もちろん、VLCの問題じゃない。

Distorted Sound From Notebook Speakers When Using VLC Media Player | Dell US

なぜだか、世間では音声の増幅というのは魔法のように行われるらしい。VLCの所謂100%以上の増幅とは、単にカーネルに流しこむビット列を変えているだけなのだ。

結論を言うと、Dellのラップトップとサポートはクソだということだ。

2014-02-09

妖怪ハウスに引っ越したことと、アマゾンの欲しい物リスト公開のこと

先月、筆者は東京に引っ越した。引っ越した先は、野方にあるシェアハウス、妖怪ハウスだ。

シェアハウスに引っ越した理由として、直接的には、今、手元に現金がほとんどないということだ。賃貸は古臭い利権と慣習に縛られており、なぜか借り手が保障費や連帯保証人などの保険のような費用をださなければならない。金を出すのはいいとして、それが月々の家賃と分離されていて、見かけ上家賃を低く見せかけているように見えることだ。これは問題だ。家賃と行った時、それは実際に払う金額の総額を言うべきであって、様々な名目で金額を分割すべきではない。たとえば、コンビニに行って100円のおにぎりを買うときに、米いくら、具いくら、包装いくら、人件費いくら、などと細かい名目で、それぞれに金をはらわないように、賃貸の世界でも、借り手が払う金額は一元化すべきである。

それはともかく、いまそのような保険費用を払う現金が手元にないし、ましてや連帯保証人なども難しいので、シェアハウスに住むのが、一番手っ取り早いと判断した。

もうひとつの理由としては、孤立を防ぐためだ。東京に係累のない筆者が、東京にやってきても、孤立するに決まっている。それに、もう一人暮らしは飽きるほどしてきたのだ。もうしばらくは十分だ。

京都にいた最後の数カ月に、吉田寮を体験したということも大きい。なるほど、こういう形で住んでいても、特に問題は起こらないのだ。

そして、去年の12月に、住むべき場所を探して、いくつかのギークハウスとシェアハウスを見学した。その結果、妖怪ハウスに住むことになった。

さて、1月の半ばに妖怪ハウスに引っ越してきた。しかし、12月に滞在したときは気にならなかったものの、実際に住みだすと気になることもあるものだ。

掃除

家の汚れだ。どうやら、ここの住人は余り総地をしないとみえて、あちこちが汚れている。特に、トイレと洗面台と風呂場がひどい。まあ、気になったものが掃除をすればいいのだ。というわけで掃除をした。それにしても、このトイレと風呂場の汚れ具合はひどい。女も住んでいるというのに、気にならないのだろうか。いや、まてしばし、この考えは男女平等の精神に反する。戒めねばならぬ。

ゴミ捨て

妖怪ハウスには、だいぶゴミが溜まっていたので、ゴミの日に捨てた。まだ燃えないゴミが、日時を逃したために残っているが、来週に捨てる予定だ。

食事

東京にやってきて驚いたのが、メシのまずさだ。どこの飯屋に入っても、京都より数百円高い上に、クソマズい。いったいどうやったらこんなにマズい作れるのだというぐらいにマズい。唯一食べられるのが、全国チェーンの安い店だ。どこでも変わらない味と値段を提供している。そんな店すらまともに思えてくるぐらい、東京の飯屋はマズい。

仕方がないので、自炊することにした。また、どうも妖怪ハウスの住人は、毎日三食定期的に食べておらず、またその食事内容もジャンクフードが多いので、やはりまともな食事を提供する必要がある。そのため、食事を作ることにした。

その他、必要なものや、やるべきことはたくさんあるのだが、とりあえずは金が必要だ。

そこで、この機会に、アマゾンの欲しい物リストを公開することにした。

Amazon.co.jp: 江添亮: 江添のほしい物リスト

アマゾンの欲しい物リストは、リストの中野商品に加えて、任意の商品を送ることができる。そうすると、とんでもなく変なものが送られてくる可能性がある。たとえば、天竜川の洗い砂などだ。一人暮らしの環境で、変なものが送られてきても、特に面白くもなんともないし、処分にも困る。ただ、このようなシェアハウスであれば、変なものが送られてきても、何かしら使いどころはあるだろうし、少なくとも笑いは取れる。ただし、どうせ変なものが送られてくるぐらいならば、最初からリストに付け加えたほうがいい。

というわけで、あらゆるジャンルから、ほしい物から、送られてきそうな変なものまで、ひと通りは付け加えた。現在、500アイテムほどある。なにか面白いものを見つけ次第に追加する。

C++に疑問がある場合や、ボードゲームがやりたい場合や、私の手料理を食べたい場合は、妖怪ハウスに来るといい。

さて、なぜ私が、にわかに東京に引っ越してきたのか。それは、東京で雇われて働くことになったからだ。では、その雇用主はどこなのか。いったい私はどんな仕事をしているのか。その謎は、来週にも明かす予定だ。

Debianの新しいinitにsystemdが採決された

Bug#727708: call for votes on default Linux init system for jessie

どうやら、Debianの新しいinitシステムは、sysvinitからsystemdになったようだ。その他の候補は、Upstartとopenrcだった。

ギークハウス南千住

昨日、歌舞伎座で心謎解色糸をみた帰りに、ギークハウス南千住に行ってきた。

昨日はあいにくと大雪で、場所を探すのに難儀した。結局、案内を乞うた。いまだに、案内なしで辿りつけたギークハウスは存在しない。

ギークハウス南千住は、主に高専生が集まって作ったシェアハウスである。シェアハウス自体で利益を出すことを目的としていないため、一人あたりの金銭的負担は小さい。

ところで、いまの住人の高専生は、もうじき卒業してしまう。卒業すると、環境が変わるので、おそらくギークハウス南千住を出て行く事になるだろう。では、ギークハウス南千住は、将来的には消失するのだろうか。この疑問を問うてみたところ、「もし、後輩が引き継ぐのであれば存続する」とのことであたt.

シェアハウスの継続は難しいものだ。

ギークハウス南千住では、高専について話を聞き、スパゲティをごちそうになった。その日は雪なので、早めに帰った。

2014-02-04

筆者近況

現在の筆者の状況について、詳細に書きたいが、色々と引越やら風邪やら新しい環境の整備や構築が立て込んでいて、ここ数週間、あまり時間がなかった。もうすべてを公表してもいいのだが、経緯などを詳細に書きたいので、要点だけを列挙する。だいたい察しがつくだろう。

今、筆者は東京に引っ越して妖怪ハウスというシェアハウスに住んでいる。住んでいる場所の詳細については、近々詳細に記事にする。

東京で仕事をしている。仕事の詳細については、近々詳細に記事にする。

すでに、2014-01-pre-Issaquah mailingが公開されている。もちろんこれは、いつものように簡易レビューするが、今回は論文の数が相当に多いし、それにせっかくの環境だから、少し丁寧に論文を読み込みたいので、いつもより時間がかかる。

このブログについても、色々と見直しが必要だ。設置してある広告についても、少し調整が必要だ。また、このブログはGFDLでライセンスされているが、記事単体を使いやすい形で提供されていない。これも、GitHubなどにも記事を上げるなど、なにか工夫が必要だ。

というわけで、色々と新しい環境での雑事に追われているので、今月はブログ記事が減るかも知れないが、これは一時的なものだ。むしろ、今年はブログ記事が増えるだろう。

しかも、これからは、このブログにおける、特にC++関連の記事が充実するだろう。同時に、ブログ以外でも、C++の啓蒙活動が活発化する。

2014-02-03

不自由なSaaSSを使った報い

BenjaminSte.in - iOS holding my phone number hostage = the worst bug I’ve ever experiencedだった

iOSが俺の電話番号を監禁している = 俺のであった中で最悪のバグ

二ヶ月前、俺はiPhoneからAndroidに移った。俺は初日からiOSのファンだったが、iOS7には我慢ならなかった(それは別の記事の話だが)

俺はVerizonのMotoXに大変満足してる。24時間以内に、今まで使ってたアプリは全部切り替えられて、Androidを俺のメインの携帯として準備することができた。

だが、よくわからないことがあったのだ。どうやら、俺はあまりテキストメッセージを受け取れていないらしい。俺のメッセージに反応がないことはイラつくし、俺も反応できないことで人をイラつかせている。

なんなんだこれは。俺の仕事用のラップトップは、まだMessages.appに設定されているので、メッセージは全部、iMessageに送られていた。ラップトップには来るが、携帯には来ないってわけだ。

こいつはイラつくが、まだ分かる。月曜日に職場に言って、iMessageを切って、それでうまくいくと思っていた。

ぜんぜんうまくいかねぇ。

これは8週間後の話で、現状はこうだ。

もし、iOS使いの友人(俺の友人の99%を占める)が俺にメッセージを送ったら、携帯は、まず、iMessage経由で送ろうと試み、失敗する。仕組みのわかってる奴らは、「テキストメッセージとして再送」というオプションを選択肢て、送ってくる。これはイラつくが、まあ、それほど最悪ってわけでもない。

もし、友人がグループメッセージに俺を含めた場合、携帯はGroup iMessageとして送る。Group MMSではないので、俺は受け取れない。ここが問題だ。静かに失敗してしまうのだ。「失敗」したという通知を受け取らない。メッセージは単に消えて、受け取ることはないし、その失敗したことを知ることもない。

Appleはこの問題を解決するために骨折りをしてくれた。残念ながら、彼らの提示した解決方法は、俺様の友人全員に俺がいたすべてのメッセージスレッドを削除するよう伝えるってぇことだ。

もういっかい状況を説明するぞ。おれはもうiPhoneを持ってないんだ。俺の電話番号は、もうAppleやiCloudやiMessageやFaceTimeに紐付けられていないんだ。だが、俺が過去五年にメッセージを送ったすべてのiOSデバイスは、俺の電話番号をキャッシュしちまってる! その携帯すべてが、俺にメッセージを送るときはiMessage経由で送ることを試みるのだ。SMSじゃねーんだ。さらに悲惨なことに、静かに失敗しちまうってこった!

しかもだな、おれが過去3年にやりとりしたメッセージは、ほとんどグループメッセージで、しかも俺の子供の写真が入ってるんだよ。俺が5年分のメッセージ履歴を削除しなきゃならないだけでも最悪なのに、俺の嫁さん、妹、大親友、それと俺の知人全員に、メッセージ履歴の削除をしろと頼めというのか? ふざけるなッ!

俺は完全に監禁された気分だぜ。Appleの奴らには解決方法がないときている。Appleが俺の電話番号を換金していて、取り戻す方法がないってのは、狂ってる。

これが、不自由で邪悪なSaaSSを使った報いである。ここまでくると、喜劇ですらある。そもそも、すでにメールやIRCといった十分に実績があり、問題が修正されてきたプロトコルがあるのに、劣化した車輪の再発明をなぜするのか。

2014-01-30

1/9998 = 0.0001 0002 0004 0008 0016 0032 0064 0128 0256...

\(\frac{1}{9998}\)は、4桁で2^13まで2の累乗のパターンが出現する。

\[\frac{1}{9998} = 0.0001\;0002\;0004\;0008\;0016\;0032\;0064\;0128\;0256\;0512\;1024\;2048\;4096\;8193\;6387\;\cdots\]

Hacker Newsによれば、これは以下のような理由による。

The pattern will break down once you get past 8192, which is 2^13. That means th\cdots | Hacker News

このパターンは8192を超えると破れる。つまり、このパターンはすごいことに52桁も継続するのだ(いや、正確には、52桁目で破れる。2の代わりに3となる)

これが動く理由は、\(9998 = 10^4 - 2\) だからだ。これを展開すると、

\[\frac{1}{10^n - 2} = \frac{1}{10^n} \times \frac{1}{1 - \frac{2}{10^n}} = \frac{1}{10^n} \times \left(1 + \frac{2}{10^n} + \frac{2^2}{10^{2n}} + \frac{2^3}{10^{3n}} + \cdots\right)\]

これにより、件のパターンが現れる。このパターンが破れるのは\(2^k\)がn桁を超える時だ。それが起こるのは、近似的に、

\[2^k > 10^n => k > \frac {n \log 10}{\log 2} \]

これにより、\(n = 4\) のとき、\(4 \times \frac{\log 10}{\log2} = 13.28\) となる。

---

他のパターンも階乗の展開で生成できる。

\[\frac{x}{(1 - x)^2} = x + 2x^2 + 3x^3 + 4x^4 + \cdots\]

\(x = \frac{1}{10^n}\) とすると、延々と続くのが、

\[\frac{1}{10^n} + \frac{2}{10^{2n}} + \frac{3}{10^{3n}} + \cdots\]

これはつまり、こうなる。

\[\frac{1}{998001} = 0.000\;001\;002\;003\;004\;005\;006\;007\cdots\]

---

他の分数の例では、

\[\frac{1000}{997002999} = 0.000\;001\;003\;006\;010\;015\;021\;\cdots\]

これは、展開結果が三角数[0]になる。あるいは、

\[\frac{1}{998999} = 0.000\;001\;001\;002\;003\;005\;008\;013\;021\;\cdots\]

これはFibonacci数[1]になる。

---

二乗列を得るのは難しいが、こうやれば、

\[\frac{1001000}{997002999} = 0.001\;004\;009\;016\;025\;036\;049\;\cdots\]

[0] : http://en.wikipedia.org/wiki/Triangle_number
[1] : http://en.wikipedia.org/wiki/Fibonacci_number

> The pattern will break down It doesn't actually: 4096 8193 6387 = \cdots | Hacker News

> パターンが破れるのは

実際には破綻しない。

      4096 8193 6387
    = 4096+8192
    +         1 6384
    +           …

返信: 俺もwolframの結果を見ていて気がついた。基本的に無限に続く数列が、オーバーフローしているというのは、変態的に美しい。

If you'd like to continue the pattern beyond 52 digits, just keep adding 9s to t\cdots | Hacker News

52桁以上のパターンを続けたいならば、元の分数に9を追加すれば良い。

\[\frac{1}{9999999999998} = 1.0000000000002\;0000000000004\;0000000000008\;0000000000016\;0000000000032\;0000000000064\;0000000000128\;0000000000256\;0000000000512\;0000000001024\;0000000002048\;0000000004096\;0000000008192\;0000000016384\;0000000032768\;0000000065536\;0000000131072\;00000002621440\cdots\;×\;10^-13\]

fibonacciの場合、分母の両側に9を付け加えればよい。

\[\frac{1}{998999} \frac{1}{99989999} \frac{1}{9999899999}\]

これによって、0が増え、オーバーフローを防げる。

これはかっこいい。

追記:

平田朋義さんが3乗列を作ってくれた。

\[\frac{333466670000}{3332000199986667} = 0.0001\;0008\;0027\;0064\;0125\;0216\;0343\;0512\;0729\;1000\;\cdots\]

平田さんによる証明は、こんな感じのものがホワイトボードに書かれていた。

\[\frac{1}{10000 - 2} = \frac{0.0001}{1 - 0.0002} = 0.0001 \times (1 + 0.002 + 0.002^2 + 0.002^3) + \cdots \]

なるほど、それで9998だったのか。それで9を足すと精度が増えるのか。

2014-01-27

ギークハウス新宿

ディベロップメントエンジニアという、企画段階で没になった資格の教本がある。この本は、全体的によく書けているのだが、デザインレビューという章がとても香ばしい。

この教本によると、デザインレビューをするには、ソースコードを印刷した紙を相手に渡し、ソースコードの原作者が、ソースコードを音読して伝えるものらしい。これをすることにより、技術者はコードに自信を持つことができる。また、デザインレビューは人事査定のために重要である。たとえ、上司や先輩が技術を知らなかったとしても、知らないなりにレビューできるという。

また、デザインレビューのために必要な部屋割りや椅子の配置方法など、わけのわからない記述が満載なのだ。

この教本の所有者によると、おそらく当時、教本を制定するときに、超有名大企業から超エライ、社内で持て余しているアホが左遷されてやってきたのではないかということだ。おそらく、その企業には出世の道は管理職になるしかなく、COBOLプログラマーとしてはそれなりに成果を上げたアホが、管理職になって悲惨なことになったのではないか。あまりに超エライために、日本語としてすら破綻しているデザインレビューの章が、査読を通ってしまい、印刷までされて、各地の教育機関にレビューするよう配られたらしい。この教本の所有者によると、おそらく当時、裏で手を回して、レビューを落とすように頼んだのではないかという話だ。

この本を紹介したところ、ギークハウス新宿に住んでいる人が、非破壊スキャナを持っているので、ぜひスキャンしようではないかという話になった。そこで、ギークハウス新宿に出かけていった。

ギークハウス新宿は、男が10人ほど一軒家で住んでいる。たまたま、全員技術者であるという。なかなかいい環境だ。

また本をスキャンした翌日、ギークハウス新宿の人間に案内してもらい、秋葉原にも行った。目的は、カタンのドイツ語版と、不自由なゲーム専用機であるファミコンとスーパーファミコンの実機だ。

残念ながら、カタンのドイツ語版は、いま日本では入手困難らしい。中古市場を回るしかないのだという。

さて、ファミコンとスーパーファミコンの実機は、無事に入手することができた。これで、いつでもレトロゲームが楽しめる。

その日は、ギークハウス新宿でピザをごちそうになった。なるほど、手作りのピザは面白い。生地から作るのは面倒だから、生地は買ってくるとして、その上に具材を載せればピザになる。妖怪ハウスでも、今度作ろうと思う。

さて、暇を見つけて、まだ行っていないギークハウスや、あるいは似たような性格のシェアハウスを、おいおいめぐってみるとしよう。

Clang VS 自由ソフトウェア

オープンソースで有名なEric S. Raymondが、自由ソフトウェアで有名なRichard Stallmanに、GCCのアンチプラグインポリシーについて突っ込んでいる。

GCCは、長年、コンパイラーのモジュール化を政治的な理由で行っていなかった。もし、例えばパーサーや意味解析だけを分離して使えるようにしたり、内部表現を規格化したりしてしまうと、GCCの一部が、不自由なソフトウェアに取り込まれたり、あるいは不自由なソフトウェアがGCCのプラグインという形で入り込むことになってしまう。これは、利用者の自由を第一とする自由ソフトウェアにとって、悪夢のような未来である。そのような未来を未然に防ぐために、政治的な理由で、GCCのはプラグインに反対するポリシーを採用している。もし、GCCを改良したければ、自由なソフトウェアとなるべきなのだ。そして、GCCのプロジェクトに参加するべきなのだ。

とはいえ、コンパイラーが機能毎に分割されていないのは不便だ。たとえば、高度なコード補完やリファクタリングのために、コンパイラーのうちのフロントエンド部分だけをテキストエディターから使いたいこともあるだろう。コンパイラーの内部表現が規格化されていれば、内部表現を生成して、そこから先のターゲット別のコード生成はコンパイラーに任せるなどといった使い方ができる。LLVMのコードは、そのような利用も、ライセンス的にも、コード的にも、簡単にできるようになっている。

GCCが市場を独占していた頃はよかったが、今やLLVMが登場し、驚異的な開発速度でGCCを追い上げている。もはやC++の規格準拠度では、完全にGCCを追い抜いている。これはGCCにとって脅威である。以前ならば、GCCでなければ事実上できなかったことが、LLVMでできるようになってきているのだ。しかも、LLVMはオープンソースという間違った目的を持っている。オープンソースと称する浅はかな思想は、利用者の自由を守ることに価値を見出さない。ああ、自由なソフトウェアの未来は暗い。

Eric S. Raymond - clang and FSF's strategy

Clangと自由ソフトウェア財団の戦略

From: esr at thyrsus dot com (Eric S. Raymond)
To: rms at gnu dot org, gcc at gcc dot gnu dot org, emacs-devel at gnu dot org
Date: Tue, 21 Jan 2014 15:19:49 -0500 (EST)
Subject: clang and FSF's strategy
Authentication-results: sourceware.org; auth=none

David Kastrupの最近のemacs-develへの質問により、私は前々から考えていた、もっとより本質的な質問を開こうと思う。一体、自由ソフトウェア財団の目的は、GCCを技術的に制限することにより達せられるものだろうか。

この問題には個人的にも興味がある。私は自由ソフトウェア財団のプロパガンダには、目的を阻害するという点で、反対している。オープンソースかつユーザーがコントロールするというソフトウェアエコシステムに、私は賛同するし、また個人的にも達成をしようと務めてきたところである。一方、自由ソフトウェア財団の遺物は良質の武器であり、GCCは確かに武器庫の中のもっと巨大な大砲だ。

私はGCCに自由ソフトウェア財団がやりたいことをやってもらいたい。自由とオープン性を啓蒙し、プロプライエタリな支配を打破し、開発ツールチェインのベンダーロックインを防ぐのだ。この目的にあたって、アンチプラグインポリシーが、いまだに妥当な方法かについて考えるべき時に来ている。

この問題には、Clangの存在が大きい。Clang開発者は、公の場で、自由ソフトウェア財団のアンチプラグインポリシーが障害であると堂々と発言していて、実際それが彼らの作業の意欲にもなっているのだ。しかも、彼らの進捗たるやすごい。今日、Clangは製品品質のツールに達し、GCCほど高機能ではないにせよ、GCCより優れた機能も提供している。例えば、Clangのエラーメッセージは、はるかに優れている。

Clang開発者は、彼らの目的はGCCを時代遅れにしてゴミ箱行きの遺物にするものである、とは言っていない。しかし、彼らの目標は、疑いようなくそこにある。3年から5年の時間で考えると、GCCの独占に対する現実の脅威となってくるだろう。

あるいは、ClangがGCCを王座から蹴り落としたら、私の目標は達成に近づくとも言える。つまり、自由ソフトウェア財団のクソな営業上の理由により、進歩を妨げて、その結果として地位を脅かされるわけなのだ。

今のところ、私はこの可能性を無視する。思うに、私としてはむしろ、GCCとClangの間で競争を促し、両方共強化させて、オープンソースツールチェイン全体を力を強めたほうがいいのだろう。

故に、自由ソフトウェア財団は、もはや自由なコンパイラーに対するプロプライエタリなベンダーのプラグインを防ぐことはできないのだ。いまや対抗馬が出てきてしまったのだ。アンチプラグインポリシーは、もはや戦略として機能しない。

また思うに、Microsoftを除いては、もはやプロプライエタリなコンパイラーを書きたいとおもうところなんて存在しないということだ。GCCはこの戦争には勝った。オープンソースのツールチェインをサポートすることによる市場の利点は、もう十分に理解されたので、新しいプロセッサーは当然のごとくサポートしているではないか。

そうであれば、GCCの制限を取っ払って、Clangと同じように、開発者の興味をひくようにするのが自然ではないのか?

Clang以前、まだGCCが市場を独占していた頃、このような制限は機能したのかもしれない。異論はある。もはや過ぎ去りし日のことを議論してもしょうがない。今や、そのような制限は無意味なものとなり、GCCの開発を妨げ、Clangの増長を許すばかりだ。

GCCには強みがたくさんある。特に、マルチプラットフォームとクロスプラットフォームサポートにおいてだ。自由ソフトウェア財団は完全にコードを自由にし、政治信条による制限を廃止し、プラグインによる豊富なエコシステムを推奨しなければならない。GCC, Clang, その他のコンパイラーを、単純に技術的な利点でのみ競争させようではないか。

過去15年の歴史が十分に実証しただろう。プロプライエタリなベンダーがオープンソースツールと、同じ土台で戦おうとすると、砂をかむことになると。しかも、彼らはその事実を、飛散な失敗から学んでいて、もはや再び試みようともしないだろう。研究費はもっと有益に費やせるのだ。

まあ、私は誰が勝とうがどうでもいい。GCCだろうとClangだろうと、私の目的は果たせるわけだ。私はどちらのツールも可能な限り最高になってほしい。そして、自由ソフトウェア財団が変化を認識して、時代の流れに追いついて欲しい。

Eric S. Raymond

There's a tendency today to absolve individuals of moral responsibility and treat them as victims of social circumstance. You buy that, you pay with your soul.

-Tom Robbins, Still Life with Woodpecker

Richard Stallman - Re: clang vs free software

Re: clang vs free software

From: Richard Stallman <rms at gnu dot org>
To: gcc at gcc dot gnu dot org
Date: Fri, 24 Jan 2014 09:54:13 -0500
Subject: Re: clang vs free software
Authentication-results: sourceware.org; auth=none
References: <CAJnXXoi2MLpZWxOxknR=mNR91JdZcHrKRsqYZSWY373fvwxObg at mail dot gmail dot com> <87eh439w1n dot fsf at uwakimon dot sk dot tsukuba dot ac dot jp> <CAJnXXojjSAWL8cqZp0X16xa81R73huywtTS90p6O3CpRaPOiDQ at mail dot gmail dot com> <jwvwqhu8zcg dot fsf-monnier+emacs at gnu dot org> <87ha8yqvup dot fsf at engster dot org> <E1W5cXI-0000j4-8x at fencepost dot gnu dot org> <CAJnXXoiuzZhjDGpvXY7psee=+bXn1rB+GdELYP0FS0CuWPqYeQ at mail dot gmail dot com> <E1W6HwP-0001WU-Tg at fencepost dot gnu dot org> <87r47zezcc dot fsf at fencepost dot gnu dot org> <m2eh3ykc3y dot fsf at gmail dot com> <20140123174934 dot GA10933 at thyrsus dot com>
Reply-to: rms at gnu dot org

[[[ 私のメールを読むNSAとFBIの職員に告ぐ ]]]
[[[ 米国憲法を内外の敵より守るために     ]]]
[[[ 諸君はSnowdenの道を辿らざるべからず  ]]]

自由ソフトウェア運動で、我々はコンピューターのユーザーの自由を啓蒙してきた。オープンソースの価値である単なる「より良いコード」という究極の目的と、自由ソフトウェアの価値は、根本的に異なるものである。もし、GCCが自由なコンパイラーから不自由なコンパイラーのプラットフォームに成り下がった場合、もはや自由という目的を果たすことはできない。故に、我々はそのような自体を阻止せずんばあらず。

自由ソフトウェアとオープンソースの詳細な違いについては、 http://www.gnu.org/philosophy/open-source-misses-the-point.htmlを参照。また http://thebaffler.com/past/the_meme_hustlerのEvgeny Morozovの全記事も参照。

ClangとLLVM開発者は、我々と共通の価値と目的を共有していないため、別の結論に達したのだ。自由を守るという我らの目的に彼らが反対する理由は、単に不便であるというだけであり、彼らにとっても必要である事柄を認識していないか、あるいはそもそも気にしていないのだ。おそらく、奴らは自分達の仕事を、「オープンソース」などと呼称し、自由についてはあまり論じていないのだろう。奴らはAppleという、自社のapp storeは不自由なソフトウェアであることを要求するほど自由を忌み嫌う企業から支援を受けている。(*)

不自由なコンパイラーがLLVMを土台にしているのは、私の正しさである、危険が現実のものであるということを如実に証明している。もし、私がGCCを不自由な組み合わせで使えるように「オープン」にしたならば、それは敗北を防ぐ助けにはならない。むしろ、敗北を早めるだけだ。

GCCが、他の技術的に優れていて、しかも同じぐらい自由を守るコンパイラーによって置き換えられたのならば、個人的には悲しいことであるが、私はコミュニティの進歩に歓喜するであろう。LLVMの存在は、我々コミュニティにとっては、退化である。なぜならば、LLVMはコピーレフトではなく、不自由コンパイラーの土台として使われ得るからである。つあmり、LLVMへの貢献は、我々の助けになるのと同様に、プロプライエタリなソフトウェアの助けにもなってしまうのだ。

退化の理由は、非コピーレフトコンパイラーが存在することにより、不自由コンパイラーの土台となりうるからである。LLVMにしろGCCにしろその他のものにしろ、コンパイラー自体は問題ではないのだ。GCCをそのような目的に提供することは、タオルを投げ入れるようなもんドア。もし、そのことによってGCCが「勝利」するのであれば、勝利など虚しい。なぜならば、本当に重要である、利用者の自由という点では、勝利していないからだ。

もし、読者は、我々がこの点で「妥協」しなければならないと考えるのであれば、http://www.gnu.org/philosophy/compromise.htmlを参照。

我々を助けるが、敵の助けにはならない唯一のコードは、コピーレフトなコードである。許諾的なライセンスで提供される自由ソフトウェアは、我々のためにはなるが、敵のためにもなってしまうのだ。もし、自分の作業に自由の利点を得たいならば、利用可能な武器を使うべきだ。すなわち、コードをコピーレフトにするのだ。私は、LLVMの主要アドオンの開発をしている者達に、コードをGNU GPL version 3 or laterで公開することを推奨する。

もし、GNUプロジェクトの目的を変更することを議論したいのであれば、適切な議論場所はgnu-misc-discuss@gnu.orgである。そちらに移動してもらいたい。

(*): もしバイナリが公開されたソースコードから生成されたものであっても、ソースコードの改変版から生成さればバイナリをインストールすることはできない。たとえソースコードが自由であっても、バイナリはプロプライエタリなのだ( http://www.gnu.org/philosophy/free-sw.htmlを参照)。Appleのapp storeのバイナリは、自由なソースコードとして公開することはできるかも知れないが、AppleのルールとAppleのDRMにより、バイナリは自由と離れないのだ。

--
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org www.gnu.org
Skype: ありえん! そいつは不自由な(自由を否定している)ソフトウェアだ。
Ekigaとか、普通の電話を使え。

2014-01-22

C++03とC++11の違い:数値ライブラリー編

C++03とC++11の違いシリーズもそろそろ終わりが近づいていきた。今回は数値ライブラリー編だ。といっても、中身はひとつ、std::complexについてだ。

変更:std::complex<T>の特殊化の表現方法が規定された

C++03では、std::complexのメモリレイアウト、すわなち、オブジェクトがストレージ上でどのように表現されているかは、規定されていなかった。C++11では、C99の複素数ライブラリーと整合性をとるために、C++における複素数ライブラリーであるstd::complexの表現方法を厳格に規定した。

これにより、実装依存のメモリレイアウトに依存しているC++03のコードは、C++11では動かなくなるおそれがある。もっとも、そのようなコードは、もともと規格が動作を保証しないコードなので、自業自得だとも言える。

さて、std::complex<:T>:の表現方法はどのように規定されたのか。それは§26.4に書いてある。簡単にまとめると以下のようになる。

今、zがlvalue式で、その型がcv std::complex<T>であり、Tがfloat, double, long doubleのいずれかであるとすると、

  • 式、reinterpret_cast<cv T(&)[2]>(z)は、正しく動く
  • 式、reinterpret_cast<cv T(&)[2]>(z)[0]は、zの実数部を意味する
  • 式、reinterpret_cast<cv T(&)[2]>(z)[1]は、zの虚数部を意味する

さらに今、cv std::complex<T> *型の式aがあったとして、a[i]は、妥当であるとすると、

  • reinterpret_cast<cv T*>(a)[2*i]は、a[i]の実数部を意味する
  • reinterpret_cast<cv T*>(a)[2*i + 1]は、a[i]の虚数部を意味する

まあ、かなりCの構造体(構造体のアドレスは実数部のアドレスと等しく、実数部と虚数部の間にパディングなし)に近いようなレイアウトになるわけだ。もちろん、C言語でもこの手の詳細は未規定なのだが。

あるいは、コードで書いたほうがわかりやすいかもしれない。もちろん、このような規定を正確に記述できる機能は標準C++にはないが、例えば以下のようなコードが、よくある環境では上のような意味になるかもしれない。

// 実装依存の例示用コード
template < typename T >
struct complex ;

template < >
struct complex<float>
{
    float real ;
    float imarginary ;
} ;

このような表現の詳細に頼ったコードは書きたくないものだが・・・、必要になるのかも知れぬ。

2014-01-21

OpenBSDに相当額の寄付が集まる

'OpenBSD Foundation Fundraising for 2014' - MARC

前回の怪しいBitcoin長者の支援表明はともかく、OpenBSDが危機的状況にあるとの声明を出してから、わずか一週間で、10万カナダドルが集まったそうだ。

List: openbsd-misc
Subject: OpenBSD Foundation Fundraising for 2014
From: Bob Beck <beck () openbsdfoundation ! org>
Date: 2014-01-20 18:49:25
Message-ID: 20140120184925.GC30292 () hogfat ! obtuse ! com

やあみんな。

一週間ほど前、OpenBSDプロジェクトが去年の経費を払う資金がない(とくに、電気代が払えない)ことと、資金提供元を維持できないことを警告した。

我々の危難のニュースは先週、広く伝わり、コミュニティからの反応と、企業の寄付には多大なものがあり、その反応の一部は、インターネットメディアにも取り上げられた。

寄付をしてくれたすべての者に告ぐ、「ありがとう」。簡単にまとめると、一週間で危険な状況から、財団への寄付が約10万カナダドルに達するほどになった。開発者として、これほどやる気を奮い立たせることはない。

我々はこの勢いに乗り、今年の資金調達目標を15万カナダドルに設定した。参照、

http://www.openbsdfoundation.org/campaign2104.html

もし、読者がすでに貢献したのならば、ありがとう
もし、読者が貢献できるのならば、してくれ
もし、この目標に到達できる人、あるいは職場を知っているのならば、連絡してくれ

-Bob

OpenBSDは、OpenSSHをも開発しているわけで、大多数の読者は恩恵を受けているだろう。

2014-01-20

あるルーマニア人のBitcoin長者、OpenBSDの危難を救うと表明、付記OpenBSDへの寄付方法

Romanian Billionaire Saves OpenBSD | Bingo Blog

ルーマニア人でBitcoin長者のMircea Popescuが、Freenodeの#openbsdに現れて、OpenBSDプロジェクトが電気代を払えないという危難に対し、2万カナダドルの支援を表明した。

引用されているログは以下の通り。

Jan 19 22:14:04 <mircea_popescu> soo, who has the authority to make a deal so I can cover the 20k shortfall 
Jan 19 22:16:24 <woopstar> mircea_popescu: you need to contact Theo
Jan 19 22:16:32 <mircea_popescu> how would i go about that ?
Jan 19 22:18:27 <woopstar> mircea_popescu: i believe his email is [redacted because email addresses don't belong in plaintext]
Jan 19 22:20:32 <mircea_popescu> woopstar ty.
Jan 19 22:20:49 <woopstar> mircea_popescu: anytime. Would be fantastic, if you can set up a deal with Theo
Jan 19 22:14:04 <mircea_popescu> で、俺が2万の穴埋めをしてやるが誰に話つけりゃいいんだ? 
Jan 19 22:16:24 <woopstar> mircea_popescu: Theoに連絡する必要があるな。
Jan 19 22:16:32 <mircea_popescu> どうやって?
Jan 19 22:18:27 <woopstar> mircea_popescu: 奴のメールアドレスは(訳注:原文にはメールアドレスがあったか?)
Jan 19 22:20:32 <mircea_popescu> woopstar thx
Jan 19 22:20:49 <woopstar> mircea_popescu: いえいえ、Theoと話がついたら、最高だな。

これを確認できる一次ソースが見つからないのだが、少なくとも、19日にfreenodeの#openbsdで、上に引用された会話が行われたことは、筆者が直接#openbsdで聞いて確かめた。

<ezoe> Is it true that a bitcoin millionaire named Mircea Popescu stated he will pay 20k shortfall in this channel yesterday? news is spreading, but I can't find the trustworthy source to confirm it.
<weezelding> ezoe: here's some speculation https://news.ycombinator.com/item?id=7087800
<Stubbe> ezoe: There is only a IRC chat that states it, nothing is sure until the money is in the bank ;)
<ezoe> weezelding, yes, I read that, and other similar online bookmarking sites.
<ezoe> Stubbe, I see. I want to know if the conversation (quoted at http://www.thedrinkingrecord.com/2014/01/19/romanian-billionaire-saves-openbsd/) happened yesterday.
<Stubbe> it did
<ezoe> Thanks.
<woopstar> it did
<woopstar> :)
<Stubbe> I know woopstar
<ezoe> oh.
<Stubbe> lol
<Stubbe> :D
<woopstar> he knows me
<woopstar> <3
<ezoe> woopstar, thanks.
<Stubbe> <3

もちろん、現時点では払うと表明しただけで、実際に金の送金は行われていないわけだが、とにかく会話の事実はあったようだ。

また、日本でPaypal経由で寄付をすることが困難、というよりも違法である現状を説明したところ、なんとOpenBSD財団は、銀行口座による寄付受付もしているということを伝えられた。国際的な銀行振込は少々面倒だし、またそもそも、カナダの非営利団体への送金が、日本で法的な寄付にあたるかどうかもわからないが、OpenBSDを金銭的に支援したい人は、以下のWebサイトにOpenBSD財団の銀行口座の情報が載っている。

Donate to the OpenBSD Foundation

風邪

今年に入って早々に風邪をひいてしまった。原因は分かっている。吉田寮の入り口の廊下にあるコタツで寝たことだ。昔から無理のきかない脆弱な肉体であるとは十分承知なのだが、やはり健康なときには、そのことを忘れてしまいがちだ。それに、吉田寮にいる間に、一度ぐらい試してみたかったのだ。

吉田寮の廊下は、ほとんど外である。特に入り口はひどい。外気が直接吹き込んでくる。コタツの外はほとんど外である。

翌朝めざめて、その日はそれほどなんともなかったのだが、やけに水っぽい鼻水が多く出るようになった。二日目から、明らかに熱があり、体がだるくなった。

困ったことに、東京に引っ越す予定の日時は、17日の夜か18日だったのだ。東京に行ってやることが多いので、出発をあまり長く遅らせたくはない。風邪を治す薬などというものが存在しない以上、病院に行ったところでどうしようもない。あるいは、インフルエンザであるという可能性もあるにはあるが、多分違うだろうと思う。

18日まで粘ってみたところ、まあ、歩けるぐらいには回復したので、東京に移動した。ただし、体がだるかった時には出ていなかった咳が出るようになった。やれやれ、人に感染させてはまずい。マスクをしよう。

もとより、吉田寮で寝るときは常にマスクを着用していた。それでこれなのだから、やはり1月に京都で外同然の場所で寝るというのは、かなり強靭な肉体が必要なのだろう。

さて、そろそろ体のだるさもだいぶ消えてきた。ただし、咳がさらに多く出る。困ったものだ。

2014-01-19

東京に引っ越した

18日に東京に引っ越した。

当分の間は、野方にある妖怪ハウスというシェアハウスに住む予定だ。もし、C++の規格について疑問があるものや、カタンを遊びたいものは、妖怪ハウスまで来るといい。

さて、私が東京に引っ越した理由であるが、もう公開してもいいのだが、まだ完全に決まっていないことがあるので、今しばらく公開を差し控えておく。

今後がどうなるにせよ、これ以上C++の規格をやるには、東京に出てこなければならないのだ。結局、日本のプログラマーのほとんどが東京にいるという事実がある。一部の一流プログラマーが、田舎で活躍することはあるにせよ、大半のプログラマーは東京にいる。現実がそうである以上、C++の規格に基づいてC++を教育するのならば、やはり東京に出てこなければならないのだ。

本も多少売れたことだし、しばらくは東京での生活が続けられる。

2014-01-17

OpenBSDが資金難で開発停止の危機

'Re: Request for Funding our Electricity' - MARC

OpenBSDが、資金枯渇で電気代が払えず、開発停止の危機が目前に迫っているようだ。

List: openbsd-misc
Subject: Re: Request for Funding our Electricity
From: Bob Beck <beck () openbsdfoundation ! org>
Date: 2014-01-14 20:03:37
Message-ID: CAComcpM_hcqQuLnb=otudLjYjwaA5wMU14EyxLCdJWEXOJoLNQ () mail ! gmail ! com

この問題に注目を集めるために取り上げる。

資金減少により、プロジェクトの経費を払うことができる資金元が必要だ。OpenBSD財団がプロジェクトの電気代を支払うために、寄付を受け付けることができるようにする必要がある。

問題は目前に迫っているのだ。電気をつけるための資金がなければ、OpenBSDは開発停止する。

もし、読者か、読者の知っている企業が、我々を支援してくれるのならば、とても喜ばしいことだが、今年に入って急激な資本枯渇に見舞われている。つまり、このプロジェクトは、金を他のことに使う前の、2万ドルの電気代を払うことができないでいる。この状況は維持できない。

On Fri, Dec 20, 2013 at 5:08 PM, Theo de Raadt <deraadt@cvs.openbsd.org> wrote:

> 電気代のための資金問題か解決されていないので
> 要請する。

> だがそれ以上にも資金が必要だ。資金が得られなければ、
> もう維持できないからだ。この要請はちっぽけなものだ。

> -------

> やあみんな

> OpenBSDプロジェクトは、開発とビルドマシンを動かすため、多大な電力を使用している。
> 輸送の問題で、マシンを空間や電力を無料で提供してくれるような場所にうごかすことはできないので、
> その方向に議論を進めないようにしよう。

> 我々が求めているのは、我々の会計ではなく、自分の会計で電気代を支払ってくれるカナダ企業だ。
> 長期に渡る支援者を求めている。

> これにより、様々なOpenBSD活動を支援することができるのみならず、
> 我々を事務作業から開放してくれる。このコストを削減できれば、
> 資金をプロジェクトの他の部分に回すことができる。

> カナダ企業が会計上の理由で最適だろう。もし、他国の企業でも
> できると思うのであれば、意見を聞きたい。

> 実際の金額をここで公表することはしない。
> 真剣に考えているなら連絡を乞う。

> Thanks

なお、OpenBSDへの寄付は、以下のWebサイトから行うことができる。

Donate to the OpenBSD Foundation

C++03とC++11の違い:アルゴリズム編

今回は、C++03からC++11にかけて変わった互換性の問題を引き起こすおそれのある、今やおなじみになったシリーズの、アルゴリズム編だ。

変更:一部のアルゴリズムの、入力の結果の挙動が、ある未規定な状態から、別の未規定の状態に変わる。

これは、C++11にムーブが導入されたためだ。std::removeやstd::remove_ifなどが該当する。

// C++03とC++11で挙動が変わる例
#include <vector>
#include <algorithm>

template < typename T >
void f( T const & t1, T const & t2, T const & t3 )
{
    // t1, t2, t3はそれぞれ等しくないオブジェクトであるとする

    std::vector<> v ;
    v.push_back( t1 ) ;
    v.push_back( t2 ) ;
    v.push_back( t3 ) ;

    // vectorの要素 { t1, t2, t3 } 

    std::remove( v.begin(), v.end(), t2 ) ;

    // vectorの要素 { t1, t3, 未規定の状態 }
}

C++03でも、C++11でも、このコードを実行した後のv[2]の状態は、未規定である。ただし、C++03では、コピーされるのに対し、C++11では、ムーブされる。そのために、未規定は未規定でも、異なる状態の未規定になる。

これは、元々が未規定の状態になるという点においては変わらないので、それほど問題になることはないだろう。C++11規格では、標準ライブラリに渡すユーザー定義型のムーブ後の状態は、未規定だが、規格の型に対する要求(たとえば、DefaultConstructibleを満たすとか)は、依然として満たしていなければならないと規定している。これはユーザーの責任でもある。

次回は数値ライブラリについて。

2014-01-14

C++03とC++11の違い: コンテナーライブラリー編

Bazaarの記事の翻訳にだいぶ時間を取られたが、C++03とC++11の違いシリーズを再開する。今回は、コンテナーライブラリーの違いについて。

変更: メンバー関数sizeの複雑度(complexity)が定数(constant)になった。

C++03では、コンテナーのメンバー関数sizeの複雑度は規定されていなかった。これにより、例えばコンテナーの要素数に比例して線形にコストが上がるような実装も可能であった。たとえば、コンテナーの内部実装がリンクリストである場合、要素数を記録するためのデータメンバーを持たずに、メンバー関数sizeが呼び出された際に、イテレーターを全てたどって要素数をその場で計算するような実装も可能であった。

そのような実装を可能にしてしまうということは、移植性を考慮したコードでパフォーマンスの予測がたたないという問題がある。そこで、C++11では、sizeの複雑性は定数とならねばらなぬと規定された。したがって、規格準拠のコンテナーは、そのように実装しなければならない。

変更: コンテナーの要件の緩和

C++11では、新たな特性を持ったコンテナーを追加した。新たな特性を持ったコンテナーをサポートするにあたり、既存の全コンテナーが満たすべき要件は、あまりにも厳しすぎるため、その要件を緩和した。これにより、全コンテナーで保証された挙動を想定しているC++03のコードが、C++11で追加された新たなコンテナーには想定外となる場合がある。

C++11で緩和された要件は以下の通り:

  • メンバー関数sizeを持たないコンテナーが存在する。size() == 0を確かめたいならば、empty()が代わりに使える。
  • 構築後に空ではないコンテナーが存在する。(std::array)
  • swap()の複雑度が定数ではないコンテナーが存在する。(std::array)

変更: ユーザー定義型にdefault constructibleの要件

sequence containerとassociative containerで、一部の操作をする際に、テンプレート実引数で与えるユーザー定義型の要件として、default constructibleが加わった。

たとえば、以下のように書いた場合

// T型の要素でサイズが10のvector
std::vector<T> v(10) ; 

T型はデフォルト構築可能でなければならない。

C++03では、これがはっきりと規定されていなかったが、C++11では、規格で明記されるようになった。

変更:一部のメンバー関数のシグネチャ変更、戻り値の型がvoidからイテレーター型になった

コンテナーの一部のメンバー関数の戻り値の型は、C++03までは、void型であると規定されていた。ただし、イテレーターを返したほうが都合が良かったり、その時点で実装上判明しているイテレーターを、後から見つけるのにコストがかかったりするため、返して欲しい場合があった。そのため、一部のメンバー関数の戻り値の型が、voidからイテレーターを返すように変更された。

変更されたのは以下のメンバー関数である。

  • erase(iter) for set, multiset, map, multimap
  • erase(begin, end) for set, multiset, map, multimap
  • insert(pos, num, val) for vector, deque, list, forward_list
  • insert(pos, beg, end) for vector, deque, list, forward_list

これらのメンバー関数の戻り値の型が、voidからイテレーター型に変わった。

これにより、C++03コードのうち、メンバー関数へのポインターをとる合法なコードが、C++11では違法になる可能性がある。逆に、C++11で合法なコードがC++03では違法になるということでもある。

// 例
#include <vector>

int main()
{
    // well-formed in C++03
    // ill-formed in C++11
    void // return type
    ( std::vector<int>::* cpp03_ptr ) // name
    // parameter-list
    ( std::vector<int>::const_iterator,
      std::vector<int>::size_type n,
      std::vector<int>::value_type const & x)
    = &std::vector<int>::insert ;


    // ill-formed in C++03
    // well-formed in C++11
    std::vector<int>::iterator // return type
    ( std::vector<int>::* cpp11_ptr ) // name
    // parameter-list
    ( std::vector<int>::const_iterator,
      std::vector<int>::size_type n,
      std::vector<int>::value_type const & x)
    = &std::vector<int>::insert ;
} 

まあ、こんなコードはあまり書かれないのではないだろうか。

変更:シグネチャ変更、一部のメンバー関数の仮引数のiteratorがconst_iteratorになった

シグネチャが変更されたメンバー関数は以下の通り。

  • insert(iter, val) for vector, deque, list, set, multiset, map, multimap
  • insert(pos, beg, end) for vector, deque, list, forward_list
  • erase(iter) for set, multiset, map, multimap
  • erase(begin, end) for set, multiset, map, multimap
  • すべての list::splice
  • すべての list::merge

これも、メンバー関数へのポインターなど、具体的なシグネチャに依存しているC++03のコードが、C++11では修正が必要になる可能性がある。稀ではあると思うが。

変更:シグネチャ変更、resizeの仮引数の値の型がリファレンスになった。

C++03では、resizeは以下のように定義されていた。

void resize(size_type sz, T c = T());

C++11では、ムーブセマンティクスを追加したため、このシグネチャも変更することになった。また、関数を分割して、オーバーロードすることにした。

void resize(size_type sz);
oid resize(size_type sz, const T& c);

リサイズで増えた要素をデフォルト構築するのが1つ目。指定された値で初期化するのが2つ目。

resizeにムーブはない。なぜならば、複数の値を、ひとつのオブジェクトを使って初期化しなければならないからだ。

次回はアルゴリズム編。

2014-01-13

プログラマーのジョーク

language agnostic - What is your best programmer joke? - Stack Overflow

私はコンピューターサイエンス科で教育しているが、何かユーモアによって場を盛り上げたい。ユーモアは場を退屈させず、物事を印象深くするし、物事を学ぶモチベージョンにもつながる。さらに、ジョークが技術的な理解を必要とするのであれば、さらにモチベーションが上がるのだ。

このstackoverflowの質問を受けて、様々なプログラマーのジョークが投稿されている。その評価順に紹介すると・・・

A man flying in a hot air balloon suddenly realizes he’s lost. He reduces height and spots a man down below. He lowers the balloon further and shouts to get directions, "Excuse me, can you tell me where I am?"

ある人が熱気球で飛んでいて、道に迷ってしまった。高度を下げて、地上にいる人を見つけた。更に高度を下げて、地上に向かって叫んだ「すみません、私はどこにいるんでしょうか?」

The man below says: "Yes. You're in a hot air balloon, hovering 30 feet above this field."

地上の人は言った「うん、君は熱気球に乗っていて、地上から30フィート上を漂っているね。」

"You must work in Information Technology," says the balloonist.

「君はITで働いているんだね」と気球乗りは言った。

"I do" replies the man. "How did you know?"

「そうだ」と地上の人は言った。「なぜ分かったんだ?」

"Well," says the balloonist, "everything you have told me is technically correct, but It's of no use to anyone."

「そうだね」と気球乗り、「君の教えてくれたことは技術的に正しい、ただ、何の役にも立たない」

The man below replies, "You must work in management."

地上の人が答えた「君は管理職だね」

"I do," replies the balloonist, "But how'd you know?"*

「そうだ」と気球乗り、「なぜわかった」

"Well", says the man, "you don’t know where you are or where you’re going, but you expect me to be able to help. You’re in the same position you were before we met, but now it’s my fault."

「そうだな」と地上の人、「お前は今どこにいるかわかっておらず、どこに向かうかもわかっていない。にもかかわらず助けを求めている。お前は会う前と変わらない状況にいるが、さて、責任は俺が負うわけだ」

これはそうとう昔からあるジョークの改変版

ノックノック

「誰だい?」

とてもながい沈黙

「java」

(;・∀・)

ご存知有名なノックノックジョーク。Javaは遅い。

A SQL query goes into a bar, walks up to two tables and asks, "Can I join you?"

SQLクエリーがバーに入って、2つのテーブルに向かって、言った。"Can I join you?"

必ずしも人とは限らない何かがバーに入るというジョーク

Saying that Java is nice because it works on every OS is like saying that anal sex is nice because it works on every gender.

JavaがあらゆるOSで動くから良いというのは、アナルセックスはあらゆる性別で行えるから良いと言うようなものだ。

コメント:これは卑猥だ! Jから始まる卑猥な単語を使わないでくれたまえ。

Jから始まるある言葉は卑猥。

Q: how many programmers does it take to change a light bulb?

A: none, that's a hardware problem.

Q: 電球を変えるのにプログラマーが何人必要か?

A: ゼロ、ハードウェアの問題である。

電球を変えるのにポーランド人が何人必要かというジョーク

A young Programmer and his Project Manager board a train headed through the mountains on its way to Wichita. They can find no place to sit except for two seats right across the aisle from a young woman and her grandmother. After a while, it is obvious that the young woman and the young programmer are interested in each other, because they are giving each other looks. Soon the train passes into a tunnel and it is pitch black. There is a sound of a kiss followed by the sound of a slap.

若いプログラマーとプロジェクトマネージャーが列車に乗り、山を超えてウィチタに向かった。空いている席は、若い女とその祖母の座っている席のみだった。しばらくして、若い女と若いプログラマーは互いに目配せをするようになった。お互いに好意を抱いていることは明らかである。やがて、列車はトンネルに入り、真っ暗闇になった。キスの音がした後に、ビンタの音がした。

When the train emerges from the tunnel, the four sit there without saying a word. The grandmother is thinking to herself, “It was very brash for that young man to kiss my granddaughter, but I’m glad she slapped him.”

列車がトンネルからでたとき、四人は無言で座っていた。祖母は思った。「あの若い男が私の孫娘にキスするだなんて。はたかれて当然だわ」

The Project manager is sitting there thinking, “I didn’t know the young tech was brave enough to kiss the girl, but I sure wish she hadn’t missed him when she slapped me!”

プロジェクトマネージャーは座ったまま思った。「あの若造が小娘にキスをするほど大胆だとは思わなかったな。だが・・・娘さん、狙いを外して私を叩きおった」

The young woman was sitting and thinking, “I’m glad the guy kissed me, but I wish my grandmother had not slapped him!”

若い女は座ったまま思った。「あの人がキスをしてくれたのは嬉しいけれど、祖母がびんたなんてしなければよかったのに」

The young programmer sat there with a satisfied smile on his face. He thought to himself, “Life is good. How often does a guy have the chance to kiss a beautiful girl and slap his Project manager all at the same time!”

若いプログラマーは座ったまま、満足気な笑みを顔に浮かべていた。彼は思った。「人生とはいいものだ。いい女にキスできて、しかもプロジェクトマネージャーにビンタできるなんて、めったにないぞ」

コメント:

プログラマーに関連したジョークではないな。登場人物を変えても通用するだろう。

これは大いにプログラマー関連だ。「いい女にキスできるなんて、めったにないぞ」とは、いかにもプログラマーだ。

やれやれ、このジョークを最初に読んだのは1980年代で、当時はアメリカ兵とロシア兵だったぞ。光陰矢のごとし。

A physicist, an engineer and a programmer were in a car driving over a steep alpine pass when the brakes failed. The car was getting faster and faster, they were struggling to get round the corners and once or twice only the feeble crash barrier saved them from crashing down the side of the mountain. They were sure they were all going to die, when suddenly they spotted an escape lane. They pulled into the escape lane, and came safely to a halt.

物理屋、エンジニア、プログラマーが車に乗り、険しい山道を運転している最中、ブレーキが壊れた。車はどんどん加速していき、危うくカーブを曲がり、一度か二度は、ガードレールがなければ転落するほどであった。彼らが皆、死を覚悟した時、脱出レーンを見つけた。脱出レーンに車を向け、ようやく安全に停止した。

The physicist said "We need to model the friction in the brake pads and the resultant temperature rise, see if we can work out why they failed".

物理屋は言った。「まずブレーキパッドの摩擦と、摩擦による温度上昇をモデル化すれば、なぜ壊れたのかわかるだろう。」

The engineer said "I think I've got a few spanners in the back. I'll take a look and see if I can work out what's wrong".

エンジニアは言った。「トランクにスパナの数本も入ってるだろうから、何が壊れたのかみてみよう」

The programmer said "Why don't we get going again and see if it's reproducible?"

プログラマーは言った。「もういちど再現するかどうか試してみるというのは?」

いかにもプログラマーらしい。

When your hammer is C++, everything begins to look like a thumb.

もしハンマーがC++だったら、すべてのものが親指に見えてくる。

指を打ってしまう。

A computer science student is studying under a tree and another pulls up on a flashy new bike. The first student asks, “Where’d you get that?”

コンピューターサイエンス科の学生が、木の下で勉強していると、別の学生が、ピカピカ新品のバイクで乗り付けた。先の学生がたずねた。「そいつをどこでてにいれたんだ?」

The student on the bike replies, “While I was studying outside, a beautiful girl pulled up on her bike. She took off all her clothes and said, ‘You can have anything you want’.”

バイクに乗った学生が答えた。「外で勉強していたら、超美人の女がバイクで乗り付けてきたんだ。その女は服を全部脱いで、「なんでもあげるわ」って言ってきたんだ」

The first student responds, “Good choice! Her clothes probably wouldn’t have fit you.”

先の学生が答えた。「そいつはいい選択だね。女物の服は君には合わないだろうしね」

その選択は正しい。

If you put a million monkeys at a million keyboards, one of them will eventually write a Java program.

もし、百万匹のサルを百万個のキーボードの前に立たせたら、彼らのうちの一匹は、いずれJavaプログラムをひとつ書くだろう。

The rest of them will write Perl programs.

残りのサルは皆Perlプログラムを書く。

さもありなん。

Q: "Whats the object-oriented way to become wealthy?"

Q: オブジェクト指向的に金持ちになる方法は?

A: Inheritance

A: 継承

["hip","hip"]

(hip hip array!)

ん?

追記:元ネタ判明、Hip hip hooray - Wikipedia, the free encyclopedia

A Cobol programmer made so much money doing Y2K remediation that he was able to have himself cryogenically frozen when he died. One day in the future, he was unexpectedly resurrected.

COBOLプログラマーはY2K問題への対処で相当に設けたので、死んだ時に自分自身を冷却保存した。未来のある日、彼は蘇生させられた。

When he asked why he was unfrozen, he was told:

彼が解凍された理由を尋ねると、曰く、

"It's the year 9999 - and you know Cobol"

今は9999年だ。お前はCOBOLを知っている。

さもありなん。

xkcd: Random Number

Programming is like sex:

プログラミングとはセックスのようなものだ:

One mistake and you have to support it for the rest of your life.

一度失敗しただけで、生涯ずっとサポートを余儀なくされる。

Software is like sex: It's better when it's free. (Linus Torvalds)

ソフトウェアとはセックスのようなものだ:フリーのほうがいい(Linus Torvalds)

Q: How many prolog programmers does it take to change a lightbulb?

Q: 電球を変えるのにPrologプログラマーが何人必要か?

A: Yes.

コメント:

Prologの長年の苦い経験からいうと、より適切な答えは、Noだ。

In Prolog programming (in contrast perhaps to life in general) our goal is to fail as quickly as possible. - The Art of Prolog/MIT Press

Prologプログラミングにおけるゴールは(人生も含めた一般論とは反対に)、できるだけ早く失敗することである。

To understand what recursion is, you must first understand recursion.

再帰とはなんであるかを理解するためには、まず再帰について理解する必要がある。

so this programmer goes out on a date with a hot chick

さて、、このプログラマーは美人とデートして、

コメント:

自慢だが、俺の嫁はラリるぐらい美人だし、デートをねだられたこともあるんだぜ

俺はプログラマーだが、大勢の美人と遊んでるぜ

こんなにユーモアのセンスのないプログラマーにひっかかる美人を見つけてきたということに驚きだ。

The fantastic element that explains the appeal of games to many developers is neither the fire-breathing monsters nor the milky-skinned, semi-clad sirens; it is the experience of carrying out a task from start to finish without any change in the user requirements.

開発者が楽しいと思うゲームとは、火を吹くモンスターや、色白ビキニのセイレーンが出てくることではない。ユーザーからの仕様変更要求なしに最初から最後までやり通せることである。

In the 1960's the KGB was very interested in learning everything possible about the American space program, sending all sorts of spies to find every possible piece of information.

1960年代のKGBは、アメリカの宇宙開発のあらゆることを知りたがっており、様々なスパイを送り込んで、どんな僅かな情報でも探らせた。

One afternoon, a breathless spy returned to headquarters with a page of paper in his hand, excitedly shouting to his superior, "Comrade! Comrade! The Americans are using Lisp to write their rocket launching software!"

ある日の午後、一人のスパイが息を切らせて本部に駆け込んできた。手には紙切れを持ってる。興奮して上官に叫んだ。「同志! 同志! アメリカ人はロケット発射ソフトウェアにLispを使っているぞ!」

The commander was skeptical. "How do you know?"

司令官は用心深かった。「なぜ分かったんだ」

"I broke into their research lab and stole a page from the teletype machine! It's not the whole program, but it's the final page and contains the concluding logic of the program! See for yourself!!!!"

「奴らの研究所にしのび混んで、テレタイプから一枚盗んできました。プログラム全部じゃないんですが、最後のページでして、プログラムの最後が載ってるんです。見てください」

The commander looked at the page and smiled:

司令官はページを見て、ニヤついた。


))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))))
))))))))))))))))))))))))))))))))))))
)))))))))))))))))))))))))))
)))))))))))))))))))))))))
))))))))))))))))))))))
))))))))))))))))))))
))))))))))))))))
)))))))))))))))
)))))))))))
))))
)))
))
))
)

Obfuscated C Contest for 1990: westley.c

There are 10 types of people in the world. Those who understand binary and those who have regular sex.

世の中には10種類の人間がいる。2進数を理解できる者と、普通のセックスをするもの。

なぜプログラマーはUNIXを好むのか:

unzip, strip, touch, finger, grep, mount, fsck, more, yes, fsck, fsck, fsck, umount, sleep

コメント:俺が見たバージョンは、

who && gawk && uname && talk && date && wine && touch && unzip && strip && touch && finger && mount && fsck && more && yes; yes; more; yes; umount && make clean && sleep

These two strings walk into a bar and sit down. The bartender says, "So what'll it be?"

二人の文字列がバーに入って座った。バーテンダーが言った。「何にします?」

The first string says, "I think I'll have a beer quag fulk boorg jdk^CjfdLk jk3s d#f67howe%^U r89nvy owmc63^Dz x.xvcu"

一人目の文字列が言った。「まずはビー=るをjdk^CjfdLk jk3s d#f67howe%^U r89nvy owmc63^Dz x.xvcu」

"Please excuse my friend," the second string says, "He isn't null-terminated."

「気にしないでくれ」と二人目の文字列が言った。「こいつはnull終端されてないんだ」

コマンドラインロシアンルーレット


[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo *Click*

Told by Gerald Weinberg in various incarnations:

Gerald Weinbergから聞いた話で、何度も改変された後だが。

A group of ten top software engineers is sent to a class for aspiring managers. The teacher walks in and asks this question:

10人のトップソフトウェアエンジニアが管理職養成セミナーに送られた。講師がやってきて、次の質問をした。

"You work for a software company which develops avionics (software that controls the instruments of an airplane). One day you are taking a business trip. As you get on the plane you see a plaque that says this plane is using a beta of the software your team developed. Who would get off?"

「あなたはavionics(飛行機の機器の制御ソフトウェア)を開発するソフトウェア会社で働いています。ある日、あなたは仕事で飛行機に乗りました。飛行機に搭乗した時に目にしたプレートには、この飛行機はあなたの開発部署が開発したソフトウェアのベータ版が使われているとあります。降りる人?」

Nine developers raised their hands. The teacher looked at the tenth and asked, "Why would you stay on?"

開発者9人が手を挙げた。講師は10人目を見て、たずねた。「なぜあなたは降りないのですか?」

The tenth said, "if my team wrote the software, the plane would not get off the ground, much less crash."

10人目が言った。「もし、うちの開発部署がソフトウェアを書いていたならば、飛行機は飛び立つことすらできませんよ。墜落なんて起こりようがない」

Once upon a time there was a shepherd looking after his sheep on the side of a deserted road. Suddenly a brand new Porsche screeches to a halt. The driver, a man dressed in an Armani suit, Cerutti shoes, Ray-Ban sunglasses, TAG-Heuer wrist-watch, and a Versace tie, gets out and asks the Shepherd:

昔々、砂漠の道の横で、羊を番する羊飼いがいた。急に、新品のポルシェがけたたましくやってきて、その場に停車した。運転手は、アルマーニのスーツを着て、セルッティの靴を履き、レイバンのサングラス、タグ・ホイヤーの腕時計、ヴェルサーチのネクタイという出で立ちで、車から降りて、羊飼いに聞いた。

Man: “If I can tell you how many sheep you have, will you give me one of them?”

男「もし、私がここに何匹の羊がいるか当てられたら、羊を一匹もらってもいいかな」

The shepherd looks at the young man, and then looks at the large flock of grazing sheep and replies:

羊飼いは若い男を見て、羊の大群を見て、答えた。

Shepherd: “Okay.”

羊飼い「いいぜ」

The young man parks the car, connects his laptop to the mobile-fax, enters a NASA Webster, scans the ground using his GPS, opens a database and 60 Excel tables filled with logarithms and pivot tables, then prints out a 150 page report on his high-tech mini-printer. He turns to the shepherd and says,

若い男は車を停め、ラップトップをモバイルFAXに接続し、NASAの衛星画像サイトに入り、GPSを使ってその場をスキャンし、対数表やピボットテーブルが満載の60枚ものExcelテーブルを開き、ハイテクなミニプリンターで150ページものレポートを印刷した。男は羊飼いの方に向き直り、言った。

Man: “You have exactly 1,586 sheep here.”

男「きっかり1586匹の羊がいるね」

The shepherd cheers,

羊飼いは微笑んだ。

Shepherd: “That’s correct, you can have your sheep.”

羊飼い「そのとおりだ。羊をやろう」

The young man makes his pick and puts it in the back of his Porsche. The shepherd looks at him and asks,

若い男は羊を選び、ポルシェのトランクに積んだ。羊飼いは男を見て聞いた。

Shepherd: “If I guess your profession, will you return my animal to me?”

羊飼い「もし、ワシがお前さんの仕事を当てられたら、羊を返してもらえるかね」

The young man answers;

若い男が答えた

Man: “Yes, why not?”

男「いいよ。やってみたまえ」

Shepherd: "You are an IT consultant."

羊飼い「あんたはITコンサルタントだな」

Man: “How did you know?”

男「なぜ分かったんだ」

Shepherd: “Very simple. First, you came here without being called. Second, you charged me a fee to tell me something I already knew, and third, you don’t understand anything about my business…Now can I have my DOG back?"

羊飼い「簡単さ。一つ、あんたは呼ばれもしないのにやってきた。二つ、ワシがすでに知ってることを教えるのに対価を要求した。三つ、あんたはワシの仕事について何も理解しておらん。さあ、ワシの「犬」を返してもらおうか」

Unix is user friendly. It's just very particular about who its friends are.

UNIXはユーザーフレンドリーである。ただ、UNIXは友達の選り好みをするだけだ。

Richard Stallman, Linus Torvalds, and Donald Knuth engage in a discussion on whose impact on computer science was the greatest.

リチャード・ストールマン、リーナス・トーバルズ、ドナルド・クヌースが、誰がコンピューターサイエンスに与えた影響が最も大きいかについて議論した。

Stallman: "God told me I have programmed the best editor in the world!"

ストールマン「俺は世界一のエディターを書いたと、神がおっしゃった」

Torvalds: "Well, God told me that I have programmed the best operating system in the world!"

トーバルズ「俺は世界一のオペレーティングシステムを書いたと、神がおっしゃった」

Knuth: "Wait, wait, I never said that."

クヌース「おいおい、ちょっと待ちなはれ。ワシ、そんなこと言うてへんで」

Knuth先生は神か。

ヤクの売人

  • 顧客を「ユーザー」と呼ぶ
  • 「最初は無料だよ」
  • 東南アジアと重要なコネを持っている(ブツを運ぶため)
  • 奇妙な符牒「スティック」、「ロック」、「ダイムバッグ」、「E」
  • 14歳から25歳までの市場に金があると知っている。
  • 仕事は、業界の生産する、より新しい、より効き目のいい調合にささえられている。
  • よく、斡旋屋やポルノ女優と一緒にいるところを目撃される
  • 製品には不健康的な中毒性がある。
  • 仕事をうまくやれば、依存する映画俳優などと寝れる。

ソフトウェア開発者

  • 顧客を「ユーザー」と呼ぶ。
  • 「無料体験版のダウンロード」
  • 東南アジアと重要なコネを持っている(コードのデバッグのため)
  • 奇妙な符牒、「スカジー」、「アイエスディーエヌ」、「ジャバ」、「ggrks」
  • 14歳から25歳の市場に金があることを知っている。
  • 仕事は業界の、より新しい、より高速な機械にささえられている。
  • よく、営業やベンチャーキャピタリストと一緒にいるところを目撃される。
  • 製品には不健康的な中毒性がある。DOOM, Quake, SimCity, Duke Nukem 3D.
  • クソ! クソ!! クソ!!!

ソフトウェア開発者とは不遇なものだ。

If your mom was a collection class, her insert method would be public.

お前のカーチャンがコレクションクラスだったら、insertメソッドはpublicだな。

お前のカーチャンを罵る形式のジョーク

Female software engineers become sexually irresistible at the age of consent, and remain that way until about thirty minutes after clinical death. Longer if it's a warm day.

女プログラマーは皆、性的な魅力を持ち、死ぬ30分前までその魅力を保つ。もし温かければ、魅力はもう少し長く保たれる。

[Scott Adams, Dilbertの作者]

This is from the 70s. It can easily be updated to the present day, but it has a certain charm just the way it is:

これは70年代のジョークだ。現代版にアップデートすることもできるが、このままにしておいたほうが面白いこともあるだろう。

Three women sat discussing their husbands and their sex lives.

3人の女が座って、それぞれの夫と性生活について話し合っていた。

"My husband's a wrestler," said the first. "He's really strong and aggressive in bed."

「夫はレスラーなの」と最初の女は言った。「ベッドではとっても強くて情熱的なの」

"My husband's an artist," said the second. "He's really gentle and sensitive."

「夫は芸術家なの」と二人目は言った。「優しくて雰囲気がいいのよ」

"My husband's an IBM salesman," said the third. "He sits on the edge of the bed and tells me how good it's going to be when I finally get it."

「夫はIBMのセールスマンよ」と三人目。「ベッドの端に座り、これからいかに素晴らしいことが起こるかを延々と話して聞かせるのよ」

The C language combines all the power of assembly language with all the ease-of-use of assembly language.

C言語はアセンブリ言語の力と、アセンブリ言語の使いやすさをあわせ持っている。

コメント:

それと、アセンブリ言語の移植性

それと、アセンブリ言語の美しさ

それと、アセンブリ言語の可読性

Three men are talking: A programmer, a doctor, and a lawyer. The lawyer says, "Man, the only way is to have a mistress. With all these divorce suits, it's terrible. The only way is to have a mistress." The doctor says, "Are you kidding? With all the STDs out there, you want a wife and that's it." The programmer says, "You need both a wife and a mistress. Because when you're not with the mistress, she'll assume you're with your wife, and when you're not with your wife, she'll assume you're with your mistress, and THAT leaves you more time to be in the lab programming!"

三人の男が話し合っていた。プログラマー、医者、弁護士である。弁護士が言った。「君たち、持つべきはセフレだよ。こんなにも離婚訴訟が多いんだ。悲惨だよ。セフレに限るね」と。医者が言った。「気は確かかね。こんなにも性病が流行っているのだぞ。妻を一人もてばそれで十分だ」と。プログラマーが言った。「妻とセフレを両方持てばいい。というのも、セフレのところに行かなければ、セフレは僕が妻のところに行っているのだと思うだろうし、妻のところにいかなければ、セフレのところに行っているのだろうと思ってくれる。これはつまり、僕がプログラミングする時間が増えるってわけだ」

まあ、たしかにプログラマーにはこういう人間が多いかも知れない。こういう人間だからプログラミングに適正があるのだろうか。

Q: how many Microsoft programmers does it take to change a light bulb?

Q: 電球を変えるのにマイクロソフトのプログラマーが何人必要か?

A: none, they just make darkness a standard and tell everyone "this behavior is by design"

0人。彼らは暗闇を標準とし、「この挙動は仕様です」と言う。

さもありなん。

How long does it take to copy a file in Vista? Yeah, I don't know either, I'm still waiting to find out.

Vistaでファイルをコピーするのにどのくらいかかるのか。俺にもわからん。まだ検証中だ。

Two bytes meet. The first byte asks, “Are you ill?”

The second byte replies, “No, just feeling a bit off.”

これは訳せない。

If the box says, "This software requires Windows XP or better," does that mean it'll run on linux?

もし箱に、「このソフトウェアはWindows XPか、上位版を必要とします」と書かれていた場合、それはつまり、linuxで動くってことか?

GNU/LinuxはWindowsよりベターだ。

If Java is the answer, it must have been a really verbose question.

もし、答えがJavaであるならば、その質問はよほど冗長な質問だったのだろう。

さもありなん。

what do Computer Science students use for birth control?

コンピューターサイエンス科の学生が避妊に用いる方法は?

Their personalities.

性格

An infinite number of mathematicians walk into a bar.

無限人の数学者がバーにやってきた。

The first orders a beer, the second orders half a beer, the third orders a quarter of a beer, the fourth an eighth, and so on.

一人目はビールを注文した。二人目はビールを半分注文した。三人目はビールを1/4注文した。4人めは1/8で、以下同様に続いた。

The bartender looks at the line going out the door,turns to the line and says "you guys suck!".

バーテンダーは行列がドアの外に続くのを見て、行列に向かって言った。「お前ら最悪だな」

Then he pours two beers and walks away.

そして、バーテンダーは二杯のビールを注ぐと、歩き去っていった。

プログラマージョークというわけではないが、おもしろい。

Why doesn't C++ have a garbage collector?

なぜC++にはガベージコレクターがないのか。

Because there would be nothing left!

なぜならば、あとに何も残らないから。

コメント:もし、JavaのGCがまともにうごいたら、プログラムの大半は残らない。

C++においては、コレクトされるのはCプリプロセッサーぐらいなものだ。

Java programming is like teenage sex ....

  • Everyone talks about it all of the time (but they don't really know what they're talking about);
  • Everyone claims to be doing it;
  • Everyone thinks everyone else is doing it;
  • Those few who are actually doing it:
    • Are not practicing it safely;
    • Are doing it poorly, and
    • Are sure it will be better next time."

Javaプログラミングは十代のセックスのようなものである。

  • みんな話をしている(だが、何を話しているか理解しているものはいない)
  • みんな、やっていると主張している。
  • みんな、他人はみんなやっていると思っている。
  • 実際にやっている極小数の者は:
    • 安全にやっていない
    • うまくやっていない。
    • 次回はもっとうまくやれると信じている。

ああ、Java、この悲惨な言語。

A programmer is walking down a road when he hears a frog say, "If you kiss me, I will turn into a beautiful woman. We can get married, and I will be your loving wife forever". The geek and the frog stare at each other for a bit, and then he picks up the frog and gently places her in his front pocket. The frog sticks her head out and says "aren't you going to kiss me?"

"No" says the programmer, "I am a programmer, I don't have time for that - but a talking frog is really cool!"

プログラマーが道を歩いていると、カエルがものを言った。「キスをしてくだされば、私はもとのお姫様に戻れます。結髮して枕席を同じくし、黄泉まで共に友為らんとす」。ギークとカエルは一瞬見つめ合った。そしてプログラマーはカエルを拾い上げると、ポケットに収めた。カエルはポケットから顔をつきだして言った。「キスしてくださらないんですの?」

「いや」とプログラマーが言った。「俺はプログラマーだ。だからそんな時間はない。でも、物を言うカエルというのはかっこいいだろ」

Your mommas so fat that not even Dijkstra is able to find a shortest path around her.

お前のカーチャンはデブすぎるんで、ダイクストラすら最短周囲を見つけられないでやんの。

どれだけ複雑な形状なのだろうか。

C++ - where your friends have access to your private members.

C++では、友達はプライベートなメンバーにアクセスできる。

Software developers like to solve problems. If there are no problems handily available, they will create their own problems.

ソフトウェア開発者は問題を解くのが好きだ。もし、お手軽な問題がなければ、彼らは問題を作り出す。

Life Before the Computer

An application was for employment
A program was a TV show
A cursor used profanity
A keyboard was a piano!

Memory was something that you lost with age
A CD was a bank account
And if you had a 3-inch floppy
You hoped nobody found out!

Compress was something you did to garbage
Not something you did to a file
And if you unzipped anything in public
You'd be in jail for awhile!

Log on was adding wood to a fire
Hard drive was a long trip on the road
A mouse pad was where a mouse lived
And a backup happened to your commode!

Cut - you did with a pocket knife
Paste you did with glue
A web was a spider's home
And a virus was the flu!

I guess I'll stick to my pad and paper
And the memory in my head
I hear nobody's been killed in a computer crash
But when it happens they wish they were dead!

面白いが、そのまま訳すことができない。

Your momma's so fat, that when she sat on a binary tree she turned it into a sorted linked-list in O(1).

お前のカーチャンは超絶にデブいので、バイナリツリーの上に座ったら、O(1)でソート済みのリンクリストに変えちまうぜ。

なんて便利なカーチャンなんだ。

The women I went to university with had this to say about their chances of meeting guys in our CS department : "The odds are good, but the goods are odd."

大学の同期の女が、コンピューターサイエンス科で、男に出会う可能性についてこう言っていた。「可能性はいいわ。でも、いいのは可能性の問題ね」

oddに含まれる二つの意味をうまく使ったいい英語のジョークであると思う。

A programmer is walking along a beach and finds a lamp. He rubs the lamp, and a genie appears. “I am the most powerful genie in the world. I can grant you any wish, but only one wish.”

プログラマーが砂浜を歩いていて、ランプを見つけた。ランプをこすると、ランプの精が現れた。「ワシは世界一強いランプの精である。何でも望みの願いを叶えてやろう。ただし、願い事はひとつだけだ」

The programmer pulls out a map, points to it and says, “I’d want peace in the Middle East.”

プログラマーは地図を引っ張りだし、指差して言った。「中東を平和にしてくれ」

The genie responds, “Gee, I don’t know. Those people have been fighting for millenia. I can do just about anything, but this is likely beyond my limits.”

ランプの精は答えた。「ううむ、それは難しいな。そのへんの奴らはもう何千年も争い続けているからして。ワシは何でも叶えられるとは言ったが、その願いはワシの力をもってしても難しい」

The programmer then says, “Well, I am a programmer, and my programs have lots of users. Please make all my users satisfied with my software and let them ask for sensible changes.”

そこでプログラマーは言った。「そうか、僕はプログラマーなんだ。僕のプログラムにはユーザーが大勢いるんだよ。僕のユーザー全員が、僕のソフトウェアに満足して、さらに大胆な変更をも受け入れるようにしてよ」

At which point the genie responds, “Um, let me see that map again.”

するとランプの精は答えた。「さて、その地図を見せてもらおうか」

My grandpa told me a non-CS variant of this several years ago. It went something like this: A young man finds a genie's lamp. He rubs it, and out pops the genie. "For freeing me from the lamp, I shall grant you one wish," the genie says. The man thinks for a moment, then says "I wish for a road to Hawaii." The genie gasps. "What a thing to ask for! Even for me it would take years to complete! Do you have a simpler wish?" The man thinks long and hard this time, then he says "I wish to understand women." The genie looks at the man, sighs, and says "You want two or four lanes on that road?"

俺のじいちゃんが、このジョークのプログラマーに関係ない派生版を昔話してくれたよ。こんな感じ。若い男がランプを見つけた。こすると、ランプの精が出てきた。「ワシをランプから自由にしてくれた礼に、願い事をひとつ叶えてやろう」とランプの精は言った。男は少し考えてから、言った。「ハワイまで行ける道がほしい」。ランプの精はうめいた。「何を考えているんだ。ワシのちからを持ってしても、そんなのは何年もかかるぞ。もっと簡単な願いはないのか」と。男は、こんどは長い間一生懸命考えて、言った。「女というものを理解したい」と。ランプの精は男を見て、ため息をつき、言った。「道は二車線か? 四車線か?」

ユーザーは、ソフトウェアの些細な変更をも嫌うものである。男が女を理解するのはかくも難しい。

Three programmers meet accidentally at the urinal while attending a technical conference. The first programmer finishes up his business, washes his hands with loads of water, walks over to the towels and uses almost the entire roll to dry his hands. He turns to the other two and says "At Microsoft, we are trained to be extremely thorough."

三人のプログラマーが、技術カンファレンスの参加中に、トイレの中で出会った。最初のプログラマーは用を足し終え、手を大量の水で洗い、タオルをほとんど使い尽くして手をふいた。彼は二人に向き直って言った。「マイクロソフトでは、やりつくせと教育されるものだ」

The second programmer finishes up, walks over to the sink and washes his hands with much less water, then uses a single towel to dry his hands. He remarks to the other two "At IBM, we are trained not only to be very thorough, but also very efficient."

二人目のプログラマーが用足しを終え、手洗い場に向かって、さっきよりだいぶ少ない量の水を使って手を洗い、たった一枚のタオルを使って手をふいた。彼は残りの二人に向き直って言った。「IBMでは、やりつくせと教育されるが、効率的にやれとも教育されるものだ」

The third programmer finishes his business, walks right past the sink and towel rack and lauds over his shoulder as he walks out the door: "At Apple we don't piss on our hands!"

三人目のプログラマーが用足しを終え、手洗い場もタオル掛けも無視して、ドアに向かいつつ、肩越しに聞えよがしに言った。「Appleでは、手に小便をひっかけたりしないものだ」

これは相当に古いジョークで、投稿主が聞いたオリジナルの話は、役者はそれぞれ、Motorolla、DEC、Sunだったらしい。

さらに古いオリジナルのジョークでは、役者は有名大学(Harvard/Yale/Dartmouthなど)だったらしい。

Q: How come there is not obfuscated Perl contest?

A: Because everyone would win.

Q: なぜ醜悪なPerlコンテストは開催されないのか?

A: 皆勝ってしまうから。

Documentation is like sex. When it's good, it's very good. When it's bad, it's better than nothing.

ドキュメントとはセックスのようなものだ。もし良かった場合、それはとても良いものだ。もし悪かったとしても、何もないよりはマシなのだ。

はて。

It's been said that if you play a windows CD backwards, you'll hear satanic chanting...worse still if you play it forwards, it installs windows.

WindowsのCDを逆再生すると、悪魔を褒め称える歌が聞こえるという。なお悪いことに、もし通常再生すると、Windowsがインストールされてしまう。

Q: How many programmers does it take to kill a cockroach?

A: Two: one holds, the other installs Windows on it

Q: ゴキブリを一匹殺すのにはプログラマーが何人必要か?

A: 二人。一人が取り押さえ、もう一人がWindowsをインストールする。

コメント: これはゴキブリの虐待だ。

不自由なWindowsのインストールとは恐ろしい。

What is your best programmer joke? | Hacker Newsに乗っていた面白いジョーク

A TCP packet walks into a bar, and says to the barman "Hello, I'd like a beer."
The barman replies "Hello, you'd like a beer?"
"Yes," replies the TCP packet, "I'd like a beer."

I'd tell you my UDP packet joke, but I'm not sure you'd get it.

TCPパケットがバーにやってきて、バーテンダーに言った。「やあ、ビールだ」
バーテンダーは答えた「やあ、ビールか?」
「そうだ」とTCPパケットが答えた「ビールだ」

UDPパケットジョークも話したいんだが、みんなに受けるかどうかわからないな。

2014-01-09

AREAのHDDケース、SD-U3HD2Cは地雷、買うべからず

私は、引っ越す前までミドルタワーのコンピューターを使っていた。さて、引っ越すにあたって、このような持ち運びに不便なコンピューターは、実家の物置に、ひとまず放り込んだ。今はラップトップも十分なパフォーマンスを持っていることだし、もはやデスクトップにこだわる理由もない。ラップトップと、まともなキーボードとマウスさえあれば、とりあえずは作業できる。固定の場所には、まともなディスプレイを設置すればいいだけだ。

さて、もうかれこれ6年ほど使っていたミドルタワーのコンピューターの処分方法を考えなければならないのだが、さしあたっての問題は、データのサルベージだ。昔のデータで、持っておきたいものがある。しかし、色々と面倒だ。

まず考えられるのは、ミドルタワーのコンピューターにインストールされたOSを起動して、何らかの方法でデータを移行する方法だ。しかし、これは色々と面倒だ。

まず、コンピューターを使える状態にしなければならない。使える状態にするというのは、電源ケーブル、ディスプレイケーブル、キーボード、マウスを接続して、安定した場所に設置しなければならない。実家で、その作業をするのはあまりにも面倒だ。

かつまた、コンピューター自体を作動させたとして、どうやってデータを移行するのだ。USB接続の大容量のストレージ経由か? LAN経由か? そのようなUSB接続の大容量のストレージは持っていないし、ルーターも持っていないので、いずれにせよ、なにか買わなければならない。

どうせ買うならば、これからも必要になりそうな機器の方がよい。SATAストレージをつなげて、USBストレージとして機能させる機器だ。一般的な正式名称はよくわからないのだが、HDDケースなどと呼ばれているようだ。

というわけで寺町に行き、SD-U3HD2Cなる製品を買った。ただし、読者はこれを買ってはならない。

SD-U3HD2C 究極なバックアップツール(titleママ)

この製品は、3.5インチのHDD、2.5インチのHDD/SSDを、二台までさすことができる。そして、二台ともUSBストレージとして使えるのだという。他にも、これ単体でストレージをクローンする機能があるそうだが、それは必要ない。ちょうどHDDが二台あるので、二台同時に扱えるのは便利だと思ったのだ。

まず、一台だけさしてみる。なぜかHDDが横に揺れる。ラップトップに接続してみるが、動作しない。なぜだろうか。別のUSBポートにさしてみるが、やはりUSBストレージとして認識されない。どういうことだろう。

不良品かと思い、返品のことを考えながら、少し雑事をして、さてまたラップトップに戻ってみると、なんとUSBストレージとして認識されていた。一応、使えるようだ。

はて、不思議なこともあるものだと、いちどUSBケーブルを抜いてから、またさしなおしてみる。すると、やはり認識されない。数分そのまま待っていると、また認識された。なんという遅さだ。

ふとみると、さっき認識されなかったUSBポートは、USB 3.0だ。はて、この製品はUSB 3.0対応と箱にデカデカと謳ってあるのだが。

ためしに、USBメモリを指してみたが、一瞬で認識された。別に持っていたUSB接続の外付けHDDをさしてみるが、やはり一瞬で認識された。あきらかに、この製品がおかしい。

さて、肝心の、二台同時に使える機能はどうだろうか。二台のHDDをさして、再び試してみる。認識に何分も待たされた挙句、なぜか一台しか認識されなかった。クソすぎる。

というわけで返品した。その日のうちであるし、店頭でも動かなかったので、すんなり認められた。

教訓としては、安物は良くないということだ。

さて、いずれにせよ、SATAストレージをUSBストレージにする変換器は必要だ。今度は、安物ではなく、定評のあるものを買わなければならない。何を買えばいいだろうか。