9

私は Xcode 4.6 を使用しており、コード全体で使用するいくつかの定数を含むヘッダー ファイルがあります。プリプロセッサ ディレクティブを適切に型付けしたいなどの理由で、プリプロセッサ ディレクティブを使用したくありません。

たとえば、.h ファイルの 1 つに次のコードがあります。

static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero";

対応する .m ファイルで使用します。

[self showToast:kErrorCannotDivideByZero];

警告が表示されます:

/path/to/my/headerFile.h:32:18: Unused variable 'kErrorCannotDivideByZero'

これが単なる警告であることはわかっていますが、これらの警告が約 50 個あり、コンパイラの出力が詰まっています。

この警告が表示される理由と、適切に解決するにはどうすればよいですか?

正当なものを取得したいので、使用されていない変数の警告をすべて単に抑制することには興味がありません。

4

6 に答える 6

16

externではなく、ヘッダーで宣言を行いますstatic。あなたがしているのは、ヘッダーを含むすべての翻訳単位の変数を作成することです。これが Clang が警告しているのは、正当に定義された変数が使用されていないためです。このexternキーワードは、変数の定義が別の場所にあることをコンパイラーに伝えます (同じ翻訳単位にあるか、別の翻訳単位にある可能性があります)。

ヘッダーには、次のものがあります。

// declare that the constant exists somewhere
extern NSString * const kErrorCannotDivideByZero;

ファイルの1.mつ (通常、ヘッダーと同じ名前を共有するファイル) に、

// define the constant, i.e. this is where it exists
NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero";

変数を宣言externすると、変数がどこで定義されているかわからなくても、コンパイラは変数を正しく処理することができます (たとえば、変数として使用することはできませんNSArray)。リンカーには、実際にどこかに定義されていることを確認する役割があります。

于 2013-02-18T23:50:53.847 に答える
13

Clang を使用すると、「診断」スタックに警告フラグをプッシュおよびポップできます: 「プラグマによる診断の制御」。次のように特定のコードをラップできます。

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"

static NSString *kErrorCannotDivideByZero = @"Error: Cannot divide by zero";

#pragma clang diagnostic pop

これらが使用されていないことを知っていることをClangに伝えるため、この特定のインスタンスでは問題ありません。

ちなみに、多くの異なる場所にインポートされているファイルでこれらの変数を定義したくない場合があります-これは、変数の再定義に関するリンカーエラーを引き起こす良い方法です(ただし、これは、変数がグローバルにリンクされている場合にのみ発生します-宣言/定義されています)なし static)。このような定数の通常のパターンは、extern 宣言をヘッダーに入れ、別のファイルで変数を定義することです。詳細については、別のクラスから静的 NSString * const を参照するを参照してください。

dreamlax が指摘しているように、ヘッダーをインポートする各ファイルがstatic変数の独自のコピーを取得するため、実際にこれらの警告が表示されます。上記の手法を提案したとき#pragma、私はあなたが何を求めているのか誤解していました.

于 2013-02-18T23:40:07.883 に答える
4

あなたの定数を作るconst

static NSString * const kErrorCannotDivideByZero = @"Error: Cannot divide by zero";

(そして、他の人が指摘したexternように、実装ファイルで使用および定義します)

于 2013-02-18T23:45:21.757 に答える
2

おそらく、それらを文字列リテラルに初期化するのではなく、ロケール固有のファイルからこれらの値をロードする初期化関数を実行して、エラーが翻訳された言語になるようにすることができます。初期化関数がその変数に割り当てられると、コンパイラは、コンパイルが成功するために変数が存在する必要があると信じたくなるかもしれません。

于 2013-02-18T23:51:11.263 に答える
1

GCC (および私は clang を想定しています) は、未使用の定数について警告しません。ここで注意すべき 1 つの落とし穴は、ポインターが const へのポインターだけでなく、const ポインターである必要があることです。そのため、警告をトリガーしない未使用の文字列定数を適切に宣言するには、次のものが必要です。

const char * const myConst = "myConst";
于 2014-09-03T11:10:48.143 に答える
0

すべての静的変数宣言をそれぞれの .m ファイルに移動できます。これにより、これらの「未使用の変数」警告がすべて取り除かれます。その理由は、静的変数がファイル レベルのスコープに制限されているためです。

于 2013-05-21T23:35:52.217 に答える