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

2012年06月21日に質問されました。  ·  閲覧回数 27.1k回  ·  ソース

Jtello picture
2012年06月21日

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

void foo (int, int);

void bar ( )
{
    //Do Stuff

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

}

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

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

回答

TartanLlama picture
2017年01月09日
31

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

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

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

Jonathan Wakely picture
2012年06月21日
30

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

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

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

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

Nawaz picture
2012年06月21日
26

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

この警告を抑制するコンパイラオプションがある可能性があります。 ただし、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の定義自体が警告を抑制します。

David Hammen picture
2012年06月21日
21

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

void foo (int, int) __attribute__ ((unused));

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

Cheers and hth. - Alf picture
2012年06月21日
2

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

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

// [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 ) {}

空の関数の呼び出しに非常に時間がかかることが心配な場合は、たとえばナノ秒が無駄になっている場合は、定義をヘッダーに移動して、 inlineという単語を追加するだけです。

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

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

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

Ameen picture
2015年01月30日
2

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

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

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

static int foo(int a, int b)
{
    // ....
}
SUPRESS_UNUSED_WARN(foo);
  • 関数とグローバル変数で使用できます
  • 仕事をするためにグローバルに配置する必要があります
  • ローカル変数には使用できません
Amit picture
2015年12月02日
1

ARMコンパイラを使用しているときのARMターゲットプラットフォームの場合、ターゲット関数の前後で次のコンパイラ指令を使用して、「警告[Pe177]:関数が宣言されましたが参照されていません」という警告メッセージを抑制します。

#pragma diag_suppress=Pe177
void foo(void)
{
/* does something but is not being called for the current build */
}
朱宏兵 picture
2019年08月17日
0
#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); }
Shivaraj Bhat picture
2015年01月30日
-4

VisualStudioプロジェクト設定で_CRT_SECURE_NO_DEPRECATEマクロを定義することもできます。

プロジェクトのプロパティ->構成のプロパティ-> C / C ++->プリプロセッサ->プリプロセッサの定義に移動します

_CRT_SECURE_NO_DEPRECATEを追加します。

それでおしまい。!