19
#include <vector>

class Object
{
};

int main()
{
    Object myObject;
    std::vector<int> myVector;
}

コンパイラは以下を出力します:

warning: unused variable 'myObject' [-Wunused-variable]

の警告はありませんmyVector。なんで?これを有効にする方法はありますか?

4

3 に答える 3

24

任意のオブジェクトを宣言する (したがって、初期化して、ある時点で破棄する) と、目に見える副作用があるかどうかは、一般的には判断できません。コンストラクタは、定義がコンパイラに認識されていない関数を呼び出している可能性があります。または、外部状態または問題を決定不能にするその他の側面に依存している可能性があります。

あなたの最初のケースでは、コンストラクターは自明です (宣言さえされていません)、デストラクタと同じです。メンバーがないため、実際には何もしないObjectことは明確で簡単に検出できObject fooます。

std::vectornew ...自明でないデストラクタ (外部状態 + 定義が不明な可能性がある関数 ( )) とともにメモリを割り当てている可能性のある自明でないコンストラクタ (外部状態 + 定義が不明な可能性がある関数 ( )) を持っていますdelete ...。この場合、宣言を削除しても安全かどうかを判断することはできません (したがって、そうすべきであることを示唆する警告を発します)。理由)。

典型的な例はstd::lock_guard、ミューテックスが構築されたときにロックし、破棄されたときに自動的にロック解除するために使用されるものです。したがって、ミューテックスは、オブジェクトがスコープ内にある限り保持されます。通常、オブジェクトにはまったくアクセスしませんstd::lock_guardが、宣言しておくと便利です。これが RAII の原則です。

このような場合に警告を発することは迷惑であり、人々が警告をオフにすることにつながり、警告が役に立たなくなる可能性があります。(コンパイラは、最適化中に宣言を削除した場合にのみ警告を発行するように設計されている場合もあります。これは、特定の最適化が有効になっている場合にのみ警告が表示される理由でもあります。)

于 2016-06-20T08:53:21.173 に答える
6

この警告は、自明な型に対してのみ生成されます。コンパイラは、コンストラクトが外部関数を呼び出すかどうかを確認できません。クラスにコンストラクターを追加するとObject、コンパイラーも警告を発行します。Gcc では、この警告を生成する必要がある型にタグを付けることができます。これを使用してこれを実行できます__attribute__((warn_unused))

http://coliru.stacked-crooked.com/a/0130c8ef29c121a1

例:

class __attribute__((warn_unused)) Object
{
    public:
    Object(){}
    void use() {}
};

int main()
{
    Object myObject;  // will give : warning: unused variable 'myObject' [-Wunused-variable]
    //myObject.use(); // uncomment to hide this warning
}

[編集]

gcc 属性ページから: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html :

warn_unused自明でないコンストラクタやデストラクタを持つ C++ 型の場合、この型の変数が参照されていない場合、その変数が本当に未使用かどうかをコンパイラが判断することはできません。この型属性は、基本型の変数と同様に、この型の変数が未使用のように見える場合に警告する必要があることをコンパイラに通知します。この属性は、std::string など、値を表すだけの型に適しています。std::lock_guard など、リソースを制御する型には適していません。

この属性は C でも受け入れられますが、C にはコンストラクタまたはデストラクタがないため不要です。

于 2016-06-20T09:05:34.100 に答える
2

上記の回答と同様に、コンパイラのドキュメントも確認してください。一部のコンパイラは、同じ警告を複数回表示しないように設定できます。「myObject」の宣言をコメントアウトすると、「myVector」に対して同じ警告が表示される場合があります。「mObject」が最初にその警告を生成すると、「myVector」の警告は表示されません。

警告が発生した場合のコンパイラの動作は、コンパイラ固有のものであるため、すべてのコンパイラが同じように動作するとは限りません。:)

于 2016-06-20T09:59:49.683 に答える