[解決済み] C++で#ifdefと#ifを使用する目的とは?
質問
私のプロジェクトのコードで、誰かが
#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つのソースファイルでデータ型を共有する必要がある場合(
struct
と
enum
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
リリースビルドのコンパイル時に
関連
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】識別子 "string "は未定義?
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】Enterキーを押して続行する
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み】'std::cout'への未定義の参照