Cで「未使用のパラメーター」警告を抑制する方法は?


210

例えば:

Bool NullFunc(const struct timespec *when, const char *who)
{
   return TRUE;
}

C ++では/*...*/、パラメーターの周りにコメントを付けることができました。もちろん、Cではエラーが発生しませんerror: parameter name omitted



4
@CiroSantilliこの質問にはより多くの投票があります。他の質問を重複としてマークすることをお勧めします。
sashoalm


-Wno-unused-parameter、それはノイズが多すぎて、特にバグをキャッチすることはめったにありません。いつ-Wshadow使用するか。
Trass3r

回答:


297

私は通常、次のようなマクロを作成します。

#define UNUSED(x) (void)(x)

このマクロは、未使用のすべてのパラメーターに使用できます。(これはどのコンパイラでも機能することに注意してください。)

例えば:

void f(int x) {
    UNUSED(x);
    ...
}

45
私は直接(void)xを使用します
Falken教授、2012年

6
これはAFAIKで唯一の移植可能な方法ですが、後で変数を使用し、roが未使用の行を削除するのを忘れた場合、これによる煩わしさが誤解を招く可能性があります。これがGCCの未使用がいい理由です。
ideasman42

6
@CookSchelling:ああ、でもそのように使うべきではありません。次のようなことをしてください:void f(int x) {UNUSED(x);}
仕事を

9
@Alcottは、(私の場合のように)関数が関数ポインタによって参照されるため、同じシグネチャを持つ必要がある多くの関数の1つである可能性があるためです。
josch 2014

17
私が使用している#define UNUSED(...) (void)(__VA_ARGS__)私は複数の変数にこれを適用することを可能にします。
マシューミッチェル

110

gccでは、unused属性に属性を使用してパラメーターにラベルを付けることができます

変数に付加されたこの属性は、変数がおそらく未使用であることを意味します。GCCはこの変数の警告を生成しません。

実際には、これは__attribute__ ((unused))パラメータの直前に置くことで達成されます。例えば:

void foo(workerid_t workerId) { }

なる

void foo(__attribute__((unused)) workerid_t workerId) { }

24
私のような初心者にとって、これは__attribute__ ((unused))議論の前に置くことを意味します。
josch '19

2
@josch私はあなたが完全に正しいと思いますが、ドキュメントはそれがパラメータのに置かれるべきであることを暗示しているようです。どちらのオプションもおそらく問題なくサポートされています。
アントニオ

また、これ__attribute__((unused))独自のGCC拡張機能です。他の一部のコンパイラでサポートされていますが、MSVCでは機能しないと思います。ただし、これは直接コンパイラー標準の一部ではないため、他のいくつかのオプションほどポータブルではありません
Zoe

58

gcc / clangの未使用の属性を使用できますが、これらのマクロをヘッダーで使用して、ソース全体にgcc固有の属性が含まれるのを回避します__attribute__

#ifdef __GNUC__
#  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
#  define UNUSED(x) UNUSED_ ## x
#endif

#ifdef __GNUC__
#  define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
#else
#  define UNUSED_FUNCTION(x) UNUSED_ ## x
#endif

その後、あなたがすることができます...

void foo(int UNUSED(bar)) { ... }

barどこかでコードで使用しようとするとエラーが発生し、誤って属性を残しておくことができないため、私はこれを好みます。

そして関数について...

static void UNUSED_FUNCTION(foo)(int bar) { ... }

注1):
私の知る限り、MSVCにはに相当するものがありません__attribute__((__unused__))

注2):かっこを含む引数ではマクロは機能しません
そのため、 実行できないような引数がある場合、または、これは、これまでに見つけたマクロの唯一の欠点です。これらの場合、フォールバックしますにUNUSED
float (*coords)[3]
float UNUSED((*coords)[3])float (*UNUSED(coords))[3]UNUSED(void)coords;


または、おそらく#define __attribute__(x)GCC以外の環境(__attribute__MSVCでサポートされているAFAIKはありません)だけですか?
フランクリンユー

これは機能しますが、dunderプレフィックス付きの用語はコンパイラ用に予約されているので、これは避けたいと思います。
ideasman42

私のgccでは、少なくとも識別子の前に属性指定子を置くと、funcs、vars、およびパラメーターに対して正しく機能するように見えるため、#define POSSIBLY_UNUSED(identifier)attribute __((__ unused))識別子のようなものを3つすべてに使用できます
Britton Kerin

私が入手した後warning: unused parameter ‘foo’ [-Wunused-parameter](gcc 7.3.0)に置いた場合
ideasman42

19

未使用の属性を使用したgccの場合:

int foo (__attribute__((unused)) int bar) {
    return 0;
}

16

これがgccとしてマークされていることを確認すると、コマンドラインスイッチを使用できますWno-unused-parameter

例えば:

gcc -Wno-unused-parameter test.c

もちろん、これはファイル全体に影響します(スイッチを設定した場所に応じてプロジェクトに影響する可能性があります)が、コードを変更する必要はありません。


7

ソースコードのブロックの未使用のパラメーター警告を抑制するgcc / g ++固有の方法は、次のプラグマステートメントでそれを囲むことです。

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
<code with unused parameters here>
#pragma GCC diagnostic pop

Clangはこれらの診断プラグマとclang.llvm.org/docs/…を
eush77

4

属性のラベル付けは理想的な方法です。MACROは時々混乱を招きます。また、void(x)を使用することで、処理にオーバーヘッドを追加しています。

入力引数を使用しない場合は、

void foo(int __attribute__((unused))key)
{
}

関数内で定義された変数を使用しない場合

void foo(int key)
{
   int hash = 0;
   int bkt __attribute__((unused)) = 0;

   api_call(x, hash, bkt);
}

ロジックにハッシュ変数を後で使用しますが、bktは必要ありません。bktを未使用として定義します。そうでない場合、コンパイラは「bkt set bt not used」と言います。

注:これは、最適化ではなく警告を抑制するためのものです。


1
を使用して処理のオーバーヘッドを追加しないvoid(x)と、コンパイラーが最適化します。
Majora320

4

同じ問題が発生しました。サードパートライブラリを使用しました。このライブラリをコンパイルすると、コンパイラ(gcc / clang)が未使用の変数について文句を言うでしょう。

このような

test.cpp:29:11:警告:変数 'magic'が設定されていますが使用されていません[-Wunused-but-set-variable] short magic [] = {

test.cpp:84:17:警告:未使用の変数 'before_write' [-Wunused-variable] int64_t before_write = Thread :: currentTimeMillis();

したがって、解決策はかなり明確です。-Wno-unusedgcc / clang CFLAGとして追加すると、-Wall設定していても、すべての「未使用」の警告が抑制されます。

この方法では、コードを変更する必要はありません。


1
未使用の警告をすべて無視したい場合はこれで問題ありませんが、ほとんどの場合はそうではありません。通常は、無視する特定のインスタンスのみです。
Dan Bechard、2016年

1

MSVCでは、特定の警告を抑制するために、コンパイラへの番号を/ wd#として指定するだけで十分です。私のCMakeLists.txtには、次のブロックが含まれています。

If (MSVC)
    Set (CMAKE_EXE_LINKER_FLAGS "$ {CMAKE_EXE_LINKER_FLAGS} / NODEFAULTLIB: LIBCMT")
    Add_definitions (/W4 /wd4512 /wd4702 /wd4100 /wd4510 /wd4355 /wd4127)
    Add_definitions (/D_CRT_SECURE_NO_WARNINGS)
Elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
    Add_definitions (-Wall -W -pedantic)
Else ()
    Message ("Unknown compiler")
Endif ()

/ wd4512 / wd4702 / wd4100 / wd4510 / wd4355 / wd4127の意味を正確に言うことはできません。MSVCに3年間注意を払っていないためですが、結果に影響しない重複警告は抑制されます。


0

このスタイルが使用されているのを見てきました。

if (when || who || format || data || len);

14
うーん。関係するすべてのパラメーターをブール値に変換できると想定しているので、これが好きだとは言えません。
Suma

1
コンパイラーはほぼ間違いなく最適化しますが、これは実際には適切な規則ではありません。何が起こっているのか本当に明確ではなく、静的なソースチェッカーを混乱させる可能性があります。ここで私見の他の提案のいずれかを使用してください。
ideasman42 2012年

1
まだ返事が来ないなんて信じられません。質問はそれがCのためであると述べました。はい、別の言語ではこれはうまくいきません。
Iustin、2013年

2
私は使用しませんが、目新しさの要素として+1します。
mgalgs

2
変数の真偽をチェックすると、構造体に対して警告が出ることがあります。例えば。struct { int a; } b = {1}; if (b);GCCは警告します、used struct type value where scalar is requiredます。
ideasman42

-1

記録として、私は上記のジョブの答えが好きですが、「何もしない」ステートメントで変数名だけを使用する解決策に興味があります。

void foo(int x) {
    x; /* unused */
    ...
}

もちろん、これには欠点があります。たとえば、「未使用」のメモがないと、意図的なコード行ではなく、間違いのように見えます。

利点は、DEFINEが必要なく、警告がなくなることです。

パフォーマンス、最適化、またはその他の違いはありますか?


2
私はこれをMSVCと一緒に使用しましたが、GCCは「影響のないステートメント」警告を発生させます。だから、ジョブの解決策は行く方法です。
ドミトリセミキン2013年

このアプローチでも、XCodeで警告が生成されます
MOK9
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.