にゃははー

はへらー

20101029(20101028?)でのエンバグ?

trivialコンストラクタとかdefault指定とかconstant expressionの仕様が変更してなければエンバグでしょう。


以下のコードがエラーとなります。

struct A
{
    int n[ 1 ];
};

struct S
{
    A a;
    S( void ) = default;
    S( int ) {}
};

S s;

エラー内容はtrivialなコンストラクタconstant expressionになってしまっているらしく、constexpr A::A()を呼び出すとA::nが初期化されていないと怒られます。
しかし、trivialなコンストラクタなコンストラクタが全てconstant expressionになってしまったわけでなく、default指定を行なったもののみがこのエラーを吐かれます。

S::S()がtrivialではなくなるものの、workaroundは

struct S
{
    A a;
    S( void ) {}
    S( int ) {}
};

S s;

とすれば問題ない様です。std::has_trivial_*_constructorでメタしてる場合は詰みますね。

追記:
更に調べたら以下の状態ですらダメでした。

struct A
{
    int i;
    A( void ) = default;
    A( int ) {}
};

A a;

どうやら条件は

  • 少なくともメンバがある
  • trivialでないコンストラクタを含む
  • trivialなデフォルトコンストラクタをdefault指定で宣言(定義)
  • trivialなデフォルトコンストラクタを用いてコンストラクトする

PODやtrivially copyableやstandard layoutといった条件については調べてないです。

しかしデータメンバまわりの初期化で変更があったということは、Non-static data member initializersが実装される予感?