C/C コードをレビューすると、使用されていない変数が頻繁に見つかります。このような未使用の変数は、さまざまな理由で発生します。この投稿では、C/C コードで未使用の変数が発生する最も一般的な原因のいくつかを見ていきます。未使用の変数についてコンパイラーに警告させる方法と、特定の未使用の変数についての警告を抑制する方法を確認します。
未使用の変数がコードベースに残る理由は数多くあります。これらには以下が含まれます:
バグと間違い: 変数が使用されない最も明白な理由は、コードに欠陥があることです。変数は実際にはまったく必要ないので削除してもよいか、変数は必要だが重要なポイントで使用するのを忘れているかのどちらかです。
リファクタリング: ソフトウェアが作成され、書き直されると、コードのセクション全体が削除される場合があります。補助計算の結果など、かつてはコードにとって不可欠であった変数が、未使用のまま残される可能性があります。
将来性: 未使用の変数は、過去のコードのレガシーとしてだけでなく、将来のコードのレガシーとしても発生する可能性があります。まだ書かれていないコードを予期して変数を宣言する場合があります。
条件付きコンパイル: 変数は、プリプロセッサのフェーズによっては未使用のままになる場合があります。標準的な例は、デバッグ目的のみに定義される変数です。コードには次の形式のものが含まれている可能性があります
const auto value = compute_some_value(); const auto value_for_comparison_only = compute_same_value_differently(); assert( value == value_for_comparison_only );
-DNDEBUG を指定してコンパイルすると、コンパイラは value_for_comparison_only が決して使用されないことを警告する可能性があります。実際、assert ステートメントは…何も置き換えられていません。
さまざまなコンパイラと警告レベルの設定は、コンパイル プロセス中に変数が未使用として報告されるかどうかに影響を与える可能性があります。
たとえば、GCC と Clang には、未使用の変数に関する警告をトリガーする -Wunused-variable フラグがあります。このフラグは -Wall 警告オプションによってすでに暗示されており、-Wno-unused-variable によってオフにできます。
私のお勧めは、常に -Wall を指定してコンパイルし、許容される場合は警告を選択的にオフにすることです。これにより、未使用の変数のすべてのインスタンスが削除されます。
常に可能な限り多くの警告を有効にしてコンパイルする必要がありますが、特定の未使用変数に関する警告を選択的にオフにしたい場合もあります。そのための一般的な方法は、 void へのキャストです:
Object unused_object; (void)unused_object;
void へのキャストは変数の (プロフォーマ) 使用としてカウントされるため、警告は発行されません。
これにより、意図したとおり、unused_object が未使用であるという警告が削除されますが、これを改善する方法があります。この void キャストが未使用のオブジェクトを意味するという明示的なセマンティクスが必要です。一般的な方法は、マクロを定義することです:
const auto value = compute_some_value(); const auto value_for_comparison_only = compute_same_value_differently(); assert( value == value_for_comparison_only );
利点の 1 つは、この変数の意図 (またはその欠落) を明示的に伝えることができるようになったことです。さらに、未使用の変数のコードをパージすることにした場合、それらの検索がはるかに簡単になります。
マクロを超えて、C 言語のネイティブ、または C/C コンパイラーによって提供される言語拡張としての変数属性があります。たとえば、Clang と GCC では、変数属性 __attribute__((unused)) を使用できます。 C 17 は [[maybe_unused]] 属性をサポートしています:
Object unused_object; (void)unused_object;
これらの属性は、これらの変数が使用されていない可能性があり、それで問題ないことをコンパイラ (そして私たち) に伝えます。
歴史的には、GCC 属性が最初に登場し、C および C のコンパイラ固有の言語拡張でした。 C 17 以降、属性は言語標準の一部です。ただし、スペルが異なるだけでなく、標準拡張と GCC 拡張では属性を配置する場所が一致していません。
[[maybe_unused]] 属性は、条件付きコンパイルを使用してほとんどのアプリケーションを見つけます。たとえば、これはデバッグ専用変数の自然な属性です。純粋に美的理由から、私は個人的にマクロ #define MAYBE_UNUSED [[maybe_unused]] を定義することを好みます。
__attribute__((unused)) の利点は、変数がコード内で使用された場合に実際に警告を発することです。 使用されていない可能性がありますではなく、絶対に使用されていないため、変数を使用すると警告が生成されます。
どうやら、未使用の変数は頻繁に使用されており、独自の言語拡張を保証するほど重要であるようです。
それに比べて、未使用の変数をコメントアウトするのは良い戦略でしょうか?いつもではありません!開発コードとデバッグ段階を通じて未使用の変数を保持しておくのには理由があります。変数が過去のバージョンのコードで使用されていたと仮定すると、古いコードを棚上げするか再統合するかをまだ決めていない可能性があります。意味: 未使用の変数が再び必要になるかどうかはわかりません。
次のようなコードを保持しておくと、デバッグ目的で役立つ場合があります。
#define UNUSED(x) (void)(x); // ... Object unused_object; UNUSED(unused_object);
複雑な計算の結果が決して使用されないとしても、それを保持しておくことは別の障害点を構成します…そしてそれはまさにデバッグ中に望むことです。元々はデバッグを目的としていなかったとしても、プログラムでこの変数を初期化すると、(再度)必要になった場合に役立ちます。
未使用の変数に関するこの投稿がお役に立てば幸いです。
以上がC/C で未使用の変数: その理由と方法?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。