1. ホーム
  2. c++

[解決済み] C++で#ifdefと#ifを使用する目的とは?

2022-03-07 07:37:08

質問

私のプロジェクトのコードで、誰かが #ifdef#if をコードに追加しました。これらを使用する目的は何でしょうか?私の知る限りでは、プリプロセッサはそのコードの内部では何もしないと言っています。以下のコードは、それらを使用するための2つの例を示しています。私は TEST_PURPOSE (true/false)が見つかりませんでした。以下のコードから、どのように #ifdef TEST_PURPOSE ? 私はビジュアルスタジオ2012を使用しています

#ifdef TEST_PURPOSE
    int i=1;
    printf("Something %d,"i);
#endif

#if 0
  int i=1;
  printf("Something %d,"i);
#endif

解決方法は?

の意味は #ifdef は、ブロック内のコードは、言及されたプリプロセッサマクロが定義されている場合にのみコンパイルに含まれることを意味します。同様に #if は、式が真と評価される場合にのみブロックが含まれることを意味します(式中に現れる未定義のマクロを0に置き換えた場合)。

ここで重要な点は、プリプロセッサはコンパイル前にソースを処理するので、ブロックが含まれないと実際のコンパイラでは全く解析されないということです。これは、この構成の重要な特徴です。

さて、なぜかC/C++がこれを採用しています。これらの言語はファイルを線形に処理するので、ソースのさらに下に現れるものはまだ知られておらず、他のソースファイルに現れるものの方が重要なのです。つまり、あるソース・ファイルにあるシンボルを他のソース・ファイルで参照する(特に型を正しくしたい)自動的な方法はないのです。つまり、プロトタイプと extern の定義で参照できるようにしました。また、2つのソースファイルでデータ型を共有する必要がある場合( structenum s)を行わなければならないでしょう。

より実用的にするために、これらをヘッダーファイルの中に置き、各ソースファイルは以下のようにすることができます。 #include (これは基本的に、実際のコンパイラが見るものの中にヘッダーファイルを挿入することを意味します)。これは、あるヘッダーファイルが別のヘッダーファイルをインクルードしてしまうという事態を招きやすく、同じファイルが2度インクルードされてしまうという事態に陥る可能性があります。を繰り返すのは無効なので struct の定義は、同じヘッダーファイルが二度定義されないようにする必要があります。 #ifndef はinclude-guardで便利です。

#ifndef HEADER_INCLUDED_
#define HEADER_INCLUDED_

// actual payload of the header file

#endif

さらに、ファイルの解析とコンパイルに長い時間がかかる場合、ヘッダのペイロードをすばやくスキップできるため、高速化につながります (前処理フェーズでは、実際のコンパイルフェーズよりもはるかに速くソースを処理します)。

もう1つの理由は、初期のCコンパイラはコードを直接アセンブラに翻訳していたため、マクロが必要だったということです。マクロを使用することで関数呼び出しを回避することができ、その結果、その場所に直接挿入され、関数呼び出しを行う代わりにその場でコードを生成することができます。同じことが、生成されたコードに直接入れる代わりに、他の場所で取得しなければならない変数である定数にも当てはまります。

3つ目の理由は、条件付きコンパイルの可能性である。ほとんどのコンパイラは、どのようなシステムのためにコンパイルされているかという情報を与えることを目的としたマクロのセットをあらかじめ定義しています。例えば、以下のようなマクロがあります。 _WIN32 は、Windows用にコンパイルしている場合にのみ定義されます。これにより、あるコード・スニペットはウィンドウズ向けだけ、別のコード・スニペットは他のプラットフォーム向けだけ、というようなことが可能になります。ほとんどのコンパイラーは、コマンドラインからカスタムマクロを設定することができます。これは、コマンドラインから(Visual Studioではプロジェクトの設定でも変更できます)、どの部分がコンパイルされるかを変更できることを意味します。そのようなマクロの中で最も顕著なものは NDEBUG マクロは、定義された場合、すべての assert を追加するのが普通です。 /DNDEBUG リリースビルドのコンパイル時に