web-dev-qa-db-ja.com

コンパイラ警告を抑制します宣言された関数は参照されません

だから私はこのようないくつかのコードを持っています:

_void foo (int, int);

void bar ( )
{
    //Do Stuff

   #if (IMPORTANT == 1)
       foo (1, 2);
   #endif

}
_

「重要」なしでコンパイルを実行すると、fooが定義されており、参照されないというコンパイラ警告が表示されます。それは私に考えさせました(それが問題です)。

したがって、これを修正するために、関数定義などの周りに同じ#if (IMPORTANT == 1)を追加して警告を削除しました。次に、その関数でその警告を抑制する別の方法があるかどうか疑問に思い始めました。 「未使用」のGCC属性を調べていましたが、関数に設定できるのと同じ属性があるかどうかわかりませんでしたか?ファイルではなくその関数に対してのみ警告を抑制する、それを抑制する別の方法はありますか?

18
Jtello

...それから、その関数でその警告を抑制する別の方法があるかどうか疑問に思い始めました。

この警告を抑制するコンパイラオプションがある可能性があります。ただし、1つのトリックはこれです:

(void)foo; //cast it to void.

この警告を抑制する必要があります。

あなたはマクロを書くことができます:

#define SUPPRESS_WARNING(a) (void)a

void foo(int thisIsAlsoAnUnsedParameter, int usedParameter)
{
   SUPPRESS_WARNING(foo); //better do this inside the definition itself :D

   SUPPRESS_WARNING(thisIsAlsoAnUnsedParameter);
}

ご覧のとおり、fooの定義自体が警告を抑制します。

23
Nawaz

関連する警告オプションは次のとおりです。

-Wunused-function
静的関数が宣言されているが定義されていない場合、または非インライン静的関数が使用されていない場合に警告します。この警告は-Wall。によって有効になります

したがって、警告はstatic関数に対してのみ与える必要があります。興味深いことです。理にかなっています。関数がstaticの場合、それは現在のファイル内でのみ使用できるため、その定義もこのファイル内にある必要があります。

そしてそれを宣言するstatic inline醜いマクロやコンパイラ固有のプラグマや属性に頼ることなく、警告を回避します。

26
Jonathan Wakely

1つの解決策は、関数属性を使用することです。

_void foo (int, int) __attribute__ ((unused));
_

これにより、gccは関数fooに対して未使用の関数警告を発行しないようになります。移植性が心配な場合は、属性をサポートするコンパイラで__attribute__ ((unused))に展開されるマクロ_UNUSED_FUNCTION_ATTRIBUTE_を定義できますが、それ以外の場合は何も展開されません。

20
David Hammen

C++ 17では、[[maybe_unused]]を使用して関数を宣言できます。

[[maybe_unused]] void foo (int, int);

これは警告を抑制し、C++ 17で未使用の可能性のある関数を表現するための正しい慣用的な方法です。

20
TartanLlama

コンパイラおよびシステムに依存するものをカプセル化する良い方法は、それをヘッダーに分解することです。次に、コンパイラとシステム、そしておそらく他のものに応じて、インクルードパスを調整します。ソースコードファイルについても同じことができます。

この場合、宣言はコンパイラまたはシステムに依存していないように思われるため、次の共通ヘッダーを追加するだけです。

// [foo.h]
#pragma once
void foo( int, int );

実装ファイル付き

// [foo.cpp]
#include <foo.virtual.cpp>

次に、何かが発生するはずのビルドの場合、インクルードパスにディレクトリを追加します。

// [foo.virtual.cpp]
#include <foo.h>
void foo( int const a, int const b )
{
    // Do the thing.
}

そして、何も起こらないビルドの場合は、インクルードパスにディレクトリを追加します。

// [foo.virtual.cpp]
#include <foo.h>
void foo( int, int ) {}

空の関数の呼び出しに非常に時間がかかる(ナノ秒の浪費など)のではないかと心配している場合は、定義をヘッダーに移動して、Word inlineを追加するだけです。

fooが他の目的にも使用される場合は、それを呼び出す関数barを定義し、barに対して上記を実行します。 fooの代わりに。

次に、すべてのプリプロセッサのものを削除しました。

プリプロセッサディレクティブコード内は適切ではないことに注意してください。

私はそれをグローバルに行う方法を見つけました、そしてそれはcでも機能します

#define SUPPRESS_UNUSED_WARN(var) \
    int _dummy_tmp_##var = ((int)(var) & 0)

次に、次のように使用します。

static int foo(int a, int b)
{
    // ....
}
SUPRESS_UNUSED_WARN(foo);
  • 関数とグローバル変数で使用できます
  • 仕事をするためにグローバルに配置する必要があります
  • ローカル変数には使用できません
1
Ameen
#define SUPPRESS_UNUSED_WARN(var) \
    int _dummy_tmp_##var = ((int)(var) & 0)

iARでは機能しません。これを変更すると機能します。

#define SUPPRESS_UNUSED_WARN(var) \
     void _dummy_tmp_##var(void) { (void)(var); }
0
朱宏兵

ARMターゲットプラットフォームの使用中、ARMコンパイラ、ターゲット関数の前後で次のコンパイラ指令を使用して、これらの警告メッセージを抑制します。

#pragma diag_suppress 177
void foo(void)
{
/* does something but is not being called for the current build */
}
0
Amit