_(void)x;
_のようなよく使用されるステートメントにより、未使用の変数x
に関する警告を抑制することができます。しかし、次をコンパイルしようとすると、よくわからない結果が得られます。
_int main()
{
int x;
(short)x;
(void)x;
(int)x;
}
_
これをg ++でコンパイルすると、次の警告が表示されます。
_$ g++ test.cpp -Wall -Wextra -o test
test.cpp: In function ‘int main()’:
test.cpp:4:13: warning: statement has no effect [-Wunused-value]
(short)x;
^
test.cpp:6:11: warning: statement has no effect [-Wunused-value]
(int)x;
^
_
したがって、void
へのキャストは、他の型へのキャストとは非常に異なり、ターゲットの型はdecltype(x)
と同じか、何か違うと結論付けます。考えられる説明に対する私の推測は次のとおりです。
(void)x;
_だけの規則ですが、他のキャストでは警告を抑制しません。すべてのステートメントは同様に効果がありません。void x;
_が有効なステートメントであるのに対し、_short x;
_は有効なステートメントではないという事実に何らかの関係があります。これらのどれがより正確であるか?ない場合、コンパイラ警告の違いはどのように説明できますか?
Voidへのキャストは、コンパイラの警告を抑制するために使用されます。 標準 §5.2.9/ 4には、
どの式も明示的に「cv void」型に変換できます。式の値は破棄されます。
この文:
(void)x;
「xの値を無視する」と言います。 void
などのタイプはありません-タイプがありません。したがって、これとは非常に異なります。
(int)x;
「整数xとして扱うx」結果の整数が無視されると、警告が表示されます(有効になっている場合)。
何もないものを無視する場合、GCCによって問題とは見なされません。また、CおよびC++で明示的に変数を無視する慣用的な方法であるvoidへのキャストであるため、正当な理由があります。
標準では、未使用のローカル変数または関数パラメーターに対して警告(標準では「診断」)を生成することは義務付けられていません。同様に、このような警告がどのように抑制されるかは強制されません。この警告を抑制するために変数式をvoid
にキャストすることは、結果がどのような方法でも使用できないため(たとえば(int)x
以外)、代わりにC以降のC++コミュニティでイディオムになりました。対応するコードが欠落しているだけです。例えば。:
(int)x; // maybe you meant f((int)x);
(void)x; // cannot have intended f((void)x);
(void)x; // but remote possibility: f((void*)x);
個人的には、この規則はまだあいまいすぎると思うので、関数テンプレートを使用したいのです。
template<typename T>
inline void ignore(const T&) {} // e.g. ignore(x);
ただし、関数パラメーターを無視する慣用的な方法は、名前を省略することです(上記参照)。この関数を頻繁に使用するのは、assert
などの条件付きでコンパイルされたコードで関数パラメーターに名前を付ける必要がある場合です。私は見つけます#ifdef NDEBUG
の使用よりも読みやすい次の:
void rate(bool fantastic)
{
assert(fantastic);
ignore(fantastic);
}
可能な用途:
auto it = list_.before_begin();
for (auto& entry : list_)
{
(void)entry; //suppress warning
++it;
}
反復子「it」は最後の要素を指します