2015-12-28 10 views
6

私は最近、clangとgccの奇妙な動作を発見しました。私は、そのメンバーの一人のために、クラスの初期化を使用して構造体(MyClass)(active)を持っている:clangとgccは、クラス内の初期化で構造体のブレースされた初期化を異なる方法で扱うのはなぜですか?

struct MyClass { 
    int something; 
    bool active = true; 
}; 

今私は中括弧で初期化するために、このクラスを試してみてください。打ち鳴らすを使用して

、私は初期化子リスト(MyClass a = { 42, true};)か、しない(MyClass a = { 42 };)でactiveを含めるかどうかを決定することができます。

しかし、gccを使用すると、activeが含まれていないと私のコードだけがコンパイルされます。そうでなければ、次のコンパイラエラーが発生します:

error: could not convert ‘{42, true}’ from ‘<brace-enclosed initializer list>’ to ‘MyClass’ 

これはバグですか?スタンダードはそれについて何を言いますか? VSC++はどうですか?ポータブルソリューションとしてどちらの方法をお勧めしますか?

Debian Linuxではgcc 4.9とclang 3.5を使用してテストされています。

+2

両方でC++ 14モードでコンパイルしていますか? – juanchopanza

+0

はい、あります。私もすべての警告を有効にしました。「ウォール」は1つしかありません。 – user3684240

+2

C++ 11では、[非静的なクラス内メンバー初期化子を持つクラスは集約ではありません](http://stackoverflow.com/q/27118535/1708801)、これはC++ 11モードでは失敗しますが両方ともC++ 14モードで成功するはずです。私は私の[回答](http://stackoverflow.com/a/27118551/1708801)にリンクされている質問にgccがこれまで5.0をサポートしていなかったことに注意しています。 –

答えて

8

このコードの動作は、C++ 11とC++ 14の間で変更されました。

C++ 11の場合、= trueの存在は、そのクラスが集合体ではないことを意味します。したがって、集約初期化を使用することはできませんでした。

C++では、クラスは依然として集合体なので、集約初期化を再度使用できます。

コンパイラの違いは、一方が他方よりも新しいことで説明できます。 compiler explorerを使用すると、gcc 4.9.xが間違っていることがわかりますが、これはgcc 5.1で修正されています。

+0

C++ 11モードでclangを使用すると、この仮説がサポートされます。それはgccと同じことについて不平を言う。 – user3684240

+0

私の推測では、これは技術的にはclangのC++ 11モードのバグですが、このコンストラクトが使用されたときに特にエラーを探していない限り、ほとんど無害です。 –

+0

@MatsPeterssonそれはclangで正しいと思われ、g ++で盗聴された –