2011-09-15

C++11のattributeは流行らない

世間では、Windows 8(仮称)の詳細の発表に湧いている。とうとう、Windows 8のDeveloper Preview版が公開されたのだ。同時に、かねてから噂されていた、Metroの詳細や、プログラミング方法も公開されている。

Building your first Windows Metro style app using C#, C++, or Visual Basic

では、さっそくC++のコード例を見てみることにしよう。

// C++
// ...
void HelloWorld::MainPage::HelloButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    DisplayText->Text = "Hello World";
}

ん? 何か違和感を覚える。非常に気になるが、先に進もう。

Platform::String^ _title;
Platform::String^ _author;
Platform::String^ _pubDate;
Platform::String^ _content;

何じゃこのdeclaratorらしき^は?

はよう、MSの独自規格スパゲッティ量産言語、C++/CLIというものならん。

と考えた私の予想はるかに上回るクソ仕様であった。

Windows Runtime objects and ref new

Note that you use the ^ (“hat”) symbol instead of the pointer dereference operator (*) when declaring the variable

そんな馬鹿な。C++/CLIではない、通常のネイティブコードを生成するC++に対する拡張だというのか。やおれMSよっく聞け。そちはC++を何と心得る。偉そうに口ヒゲなど生やしてる場合か。もっとも、最近は剃っているそうだが。そもそも、declaratorとしての*は、declaratorであり、ポインターデリファレンス演算子ではない。爾、C++規格を知らざる者にドキュメントを書かせたるか。

結局、これがMSの選択か。attributeではなく、特別なdeclarator、^を選んだということか。

もちろん、MSを標準規格に従わない、常に独自規格を再発明する、独裁者だと批判するのは容易であるが(実際、その通りであるが)、もう少し考えてみる。MSはdeclaratorに^を使うことには、合理的な理由がある。C++/CLIで全く同じ構文を提供しているので、実装経験と実績があるのだ。この構文に決定するにあたって、既存のC++コードとの互換性を保てるかどうか、相当な検証を行ったはずである。C++/CLIとは、既存のC++のコード資源が使えるという利点のみが、C#より優れているのであって、C++のコード資源の利用が必要なければ、まともな頭をしていれば、普通はC#を選ぶはずだ。

もちろん、attributeも互換性に関しては申し分ないが、実装経験の差で、選ばれなかったのだろう。実際の実装で使われないならば、規格には意味がない。

言語拡張自体は、悪いことではない。C++の標準規格は、どの実装でも必ずサポートされるべき最小限の必須機能だけを規定している。たとえば、C++98の時点では、アライメントの指定は、あらゆる環境でサポートされるべき必須機能ではなかった。それ故、MSVCやGCCその他の、アライメント指定を必要とするコンパイラーは、#pragmaや独自のキーワードを用いた言語拡張によって、アライメント指定をサポートしていた。

C++11では、このような言語拡張の中でも、とくにコードに付加的な意味を与える要素に着目して、attributeという文法を付け加えた。これを使えば、独自の汚いキーワード(例:__declspec、__attribute__)を導入することなく、言語拡張が行えるはずであった。少なくとも、机上の理論ではそうであった。

しかし、__declspec(hogehoge)と[[hogehoge]]では、汚さには余り変わりはない。むしろ、attributeの方が見た目に宜しくないとも言える。

だいたい、C++11の機能からして、当初attributeで提供されるはずだった、アライメント指定やoverrideやfinalといった機能は、「公式な標準規格の言語機能は独自のキーワードを与えられる資格がある」という理由で、独自のキーワードを与えられた(厳密に言うと、キーワードではなく、contextual keywordなのだが)。あとに残ったのは、carries_dependancyとnoreturnという、まあ、言わば、それほど重要ではない機能だけである。

おそらく、attributeはasmと同じ轍を踏むだろう。どの実装からも顧みられることなく、黒歴史となるのだ。

No comments: