22

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

void foo (int, int);

void bar ( )
{
    //Do Stuff

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

}

"IMPORTANT" なしでコンパイルすると、foo is defined and never referenced というコンパイラの警告が表示されます。それは私に考えさせました(それが問題です)。

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

4

9 に答える 9

36

C++17 では、次のように関数を宣言できます[[maybe_unused]]

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

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

于 2017-01-09T15:43:11.100 に答える
31

関連する警告オプションはこれだと確信しています:

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

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

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

于 2012-06-20T18:43:29.853 に答える
27

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

この警告を抑制するコンパイラ オプションがある場合があります。ただし、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それ自体の定義によって警告が抑制されます。

于 2012-06-20T17:34:07.757 に答える
21

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

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

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

于 2012-06-20T17:51:13.577 に答える
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、それを呼び出す関数を定義して、発生するか発生しないかを決定し、 for のbar代わりに for を実行しfooます。

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

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

于 2012-06-20T17:52:47.830 に答える
1

ARM コンパイラを使用している ARM ターゲット プラットフォームの場合、ターゲット関数の周りに次のコンパイラ ディレクティブを使用して、「警告 [Pe177]: 関数は宣言されていますが、参照されていません」という警告メッセージを抑制します。

#pragma diag_suppress=Pe177
void foo(void)
{
/* does something but is not being called for the current build */
}
于 2015-12-02T12:36:44.757 に答える
-4

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

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

_CRT_SECURE_NO_DEPRECATE を追加します。

それでおしまい。!

于 2015-01-30T09:08:37.523 に答える