23
struct Bar
{
    Bar() {}
};


struct Foo
{
    Foo() = default;
    Bar m_bar;
};

int main()
{
    Foo foo;
}

C++11defaultキーワードと gcc warningを使用すると-Weffc++、gcc は次のように出力します。

警告: 'Foo::m_bar' はメンバー初期化リストで初期化する必要があります [-Weffc++]

この警告を無視しても安全ですか? gcc にバグを報告する必要がありますか?

4

2 に答える 2

29

警告を無視または抑制することができます。これは、EffectiveC++ガイドラインの1つの誤解です。ガイドラインでは、割り当てよりも初期化を優先すると述べていますが、あなたの例でm_barは、初期化されます。あなたのコードは正しいです。

出典:GCCのバグトラッカーのJonathan Wakely :

#項目12:コンストラクターでの代入よりも初期化を優先します。

アイテム4に置き換えられました:「オブジェクトが使用される前にオブジェクトが初期化されていることを確認してください」、G ++はとにかく元のアイテムを誤って解釈し 、mem-initializerのないメンバーについて警告します。これは非常に迷惑です:stdを初期化する意味はありません::文字列、それは完全に安全なデフォルトコンストラクタを持っています。PR 2972​​の私の-Wmeminitパッチは、コンストラクターによって初期化されていないメンバーについてのみ警告するため、このアイテムの現在の警告を置き換える必要があります。

(これは既知の問題であるため、バグとして再度報告する必要はありません。)

于 2012-12-22T11:46:13.477 に答える
6

この警告を無視してもよろしいですか? はい。

この警告を無視してもよろしいですか? 依存(*)

gcc にバグを報告する必要がありますか? いいえ(*)

(*)

  • default実際、コンストラクターはm_bar問題なく初期化されます。それをテストできます
  • g ++がそれを取得しないのは少し奇妙です
  • 非常に詳細な警告設定を選択しました
  • 警告はコードの正確さではなく、スタイルに関するものです
  • これを修正して、Foo のデフォルト コンストラクターと Bar のカスタム コンストラクターを保持することはできません。

man g++、セクション -Weffc++

Scott Meyers の『Effective C++ book』にある次のスタイル ガイドラインの違反について警告します。

  • 項目 11: 動的に割り当てられたメモリを持つクラスのコピー コンストラクターと代入演算子を定義します。
  • 項目 12: コンストラクターでの代入よりも初期化を優先します。
  • 項目 14: 基本クラスでデストラクタを仮想化します。
  • 項目 15: "operator=" に *this への参照を返すようにします。
  • 項目 23: オブジェクトを返さなければならないときに、参照を返そうとしないでください。

また、Scott Meyers の More Effective C++ book からの次のスタイル ガイドラインの違反についても警告します。

  • 項目 6: インクリメント演算子とデクリメント演算子の前置形式と後置形式を区別する。
  • 項目 7: 「&&」、「││」、または「,」をオーバーロードしないでください。

このオプションを選択する場合、標準ライブラリ ヘッダーはこれらのガイドラインのすべてには従わないことに注意してください。

于 2012-12-22T12:02:55.823 に答える