meryngii.neta

今日も新たな"ネタ"を求めて。

属性(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();

統一された関数宣言も組み合わせると、関数宣言だけでブラケットだらけになりそうな予感が…。