属性(attribute)
N2798には属性(attribute)に関する記述が追加されています。誰も解説していないようなので簡単な紹介を書きます。
属性は型、変数、名前、ブロック、翻訳単位に情報を付加するもので、
[[attribute]]
のように、ブラケット二つで囲まれた中に記述します。
C#ではブラケット一つですが、C++では二つです。
宣言の中では、
int var[[attribute]]; char arr[[attribute]][123]; class x [[attribute]] { }; void [[attribute]] f();
こんな位置に置かれます。これによって、今まで実装依存だった修飾の方法が統一されることになります。
属性は引数のような形でさらに情報を加えることができます。また、カンマで並べることもできます。
align
アライメント指定として予約語になる予定だったalignasは廃止され、align属性が代わりに追加されました。
int var[[align(2)]];
align属性は定数式か型を取ることができます。定数式は整数のみ返すことができます。
[[align(double)]]
のように型を取ると、
[[align(alignof(double))]]
の意味になります。
noreturn
関数がリターンしないことを指定します。と言われてもよく分からんので調べました。要するに、例外などで関数が普通に返ってこないことを指定するようです。
VC++やGCCでは独自拡張として__declspec(noreturn)などを実装しているようです。
void f [[noreturn]] () { throw "error"; // OK } void q [[noreturn]] (int i) { // i <= 0 のときの振る舞いが未定義 if (i > 0) throw "positive"; }
エラー処理を統一した関数などに使って最適化を狙うのだと思います。
final
Javaのfinal、C#のsealedと大体似ています。継承先での指定された仮想関数のオーバーライドを禁止します。
struct B { virtual void f [[ final ]] (); }; struct D : B { void f(); // ill-formed };
クラスに指定された場合は、全ての仮想関数に指定されたと同じとみなすようです。Javaのfinalはクラスを継承できないという意味だったはずなので、この部分は他の言語と違うような気がします。(紛らわしい微妙な相違が生まれそうな予感)
carries_dependency
これはよく分かりません。多分スレッド間のメモリについて指定するものだと思います。詳しい方いらっしゃいましたら教えてください。
その他
__stdcallなどもこんな風に書けるようになるのかもしれません。
void [[stdcall]] func();
統一された関数宣言も組み合わせると、関数宣言だけでブラケットだらけになりそうな予感が…。