web-dev-qa-db-ja.com

「参照されていない仮パラメータ」の警告を避ける

私はこのようなスーパークラスを持っています:

class Parent
{
public:
    virtual void Function(int param);
};

void Parent::Function(int param)
{
    std::cout << param << std::endl;
}

..そして次のようなサブクラス:

class Child : public Parent
{
public:
    void Function(int param);
};

void Child::Function(int param)
{
    ;//Do nothing
}

サブクラスの.cppファイルをコンパイルすると、このエラーが発生します

warning C4100: 'param' : unreferenced formal parameter

慣例として、以前は警告をエラーとして扱っていました。上記の警告を回避する方法は?

ありがとう。

46
bdhar

C++では、名前を使用していないというパラメーターを指定する必要はないので、これを行うことができます。

void Child::Function(int)
{
    //Do nothing
}

ただし、ドキュメントとしてヘッダーファイルの宣言にパラメーター名を保持することもできます。空のステートメント(;)も不要です。

85
CB Bailey

コンパイラーに自分の意図だけでなく、コードの他のメンテナーにも伝え、マクロは後で検索できるため、マクロの使用を好みます。

引数名をコメントアウトする方法は、コードに不慣れな人(または6か月後の私)に簡単に見逃される可能性があります。

ただし、これはスタイルの問題であり、生成されるコード、パフォーマンス、または堅牢性に関して、どちらの方法も「優れた」ものでも、より最適なものでもありません。私にとって決定要因は、標準化されたシステムを通じて他の人に私の意図を知らせることです。パラメーター名を省略してコメントを入力しても同様に機能します。

_void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
    UNREFERENCED_PARAMETER(pNMHDR);
_

代わりに:

_void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult)
{
    // Not using: pNMHDR
_

最悪の解決策は、警告メッセージを抑制することです。ファイルまたはプロジェクト全体に影響を与え、何かを見落としているかもしれないという知識を失います。少なくともマクロを追加するか、引数名をコメントアウトすることで、この引数を使用しないという意識的な決定を下したことと、間違いではないことを他の人に伝えました。

WinNT.hのWindows SDKは、UNREFERENCED_PARAMETER()およびDBG_UNREFERENCED_PARAMETER()とともにDBG_UNREFERENCED_LOCAL_VARIABLE()を定義します。それらはすべて同じことを評価しますが、違いは、開始時にDBG_UNREFERENCED_PARAMETER()が使用され、コードがより完成したときにパラメーターを使用することを期待することです。パラメータを使用しないことが確実な場合は、UNREFERENCED_PARAMETER()バージョンを使用してください。

Microsoft Foundation Classes(MFC)にも同様の規則があり、UNUSED()およびUNUSED_ALWAYS()マクロが短くなっています。

スタイルを選択し、それに固執します。そのようにすると、コード内で「_DBG_UNREFERENCED_PARAMETER_」を検索し、引数を使用する予定であるが使用しなかったインスタンスを見つけることができます。一貫したスタイルを採用し、習慣的にそれを使用することで、後で他の人や自分自身にとっても簡単になります。

28

パラメーター名を保持する場合に使用できる別の手法は、voidにキャストすることです。

void Child::Function(int param)
{
    (void)param;   //Do nothing
}
19

@Charles Baileyが言及したように、パラメーター名はスキップできます。

ただし、特定のシナリオでは、デバッグビルドではASSERT()を呼び出していますが、リテールビルドではnopであるため、パラメーター名が必要です。これらのシナリオには、(少なくともVC++では:-))UNREFERENCED_PARAMETER()という便利なマクロがあります。これは次のように定義されています。

#define UNREFERENCED_PARAMETER(x) x

@R Samuel Klatchkoが投稿した単純なキャストも機能しますが、これが参照されていないパラメーターと説明されていない単純なキャストであることがコードで明示されている場合、個人的に読みやすいことに注意してください。

8
Franci Penov

プラグマは、VSを使用していることが明らかなので、うまく機能します。この警告は、参照されていないパラメーターがコールバックインターフェイスと派生メソッドで非常に一般的であることを考えると、非常に高いノイズ対利益比を持っています。 W4を使用するMicrosoft Windows内のチームでさえ、その無意味さにうんざりして(/ Wallに適している)、プロジェクトに追加されただけです。

#pragma warning(disable: 4100)

コードブロックのみの警告を軽減する場合は、次のように囲みます。

#pragma warning(Push)
#pragma warning(disable: 4100)
void SomeCallbackOrOverride(int x, float y) { }
#pragma warning(pop)

パラメーター名を省略する習慣には、デバッガーの欠点があり、名前で簡単に検査したり、ウォッチに追加したりできません(参照されていないパラメーターが複数ある場合は混乱します)。パラメータを使用しない場合があります。その値を知っていると、プロセスのどの段階にいるのかがわかります。特に、呼び出しスタック全体が上にない場合に役立ちます。

5
Dwayne Robinson

マクロを使用して、参照されていない仮パラメーターの警告を抑制します。

#define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) )

これには次の利点があります。

  • #define UNUSED(x)(void)xとは異なり、以前はそのような必要性が存在しなかった可能性がある場合に、パラメーターの型の完全な定義を確認する必要はありません。
  • #define UNUSED(x)&xとは異なり、単項&演算子をオーバーロードする型のパラメーターで安全に使用できます。
4
TheBeardyMan