ぴぐノート

Good code is its own best documentation.

C/C++ プログラミング言語

C++のプリプロセッサの復習をしよう その2 【#defineの活用】

投稿日:

前回に引き続き、C++のプリプロセッサの復習です。
前回は#includeと#defineについて記事にしましたが、【まとめ】にも記載の通り、#defineと関連するプリプロセッサは多くあります。

今回は「#ifdef (#if defined)」「#ifndef (#if ! defined)」「#undef」について記事にしようと思います。
実際の開発でもデバッグなどで活用の幅が広いので、普段から使い方に慣れておくと、人のソースを読み込む際に役立ちます。

前回の記事はちょっと雑すぎたので、まずプリプロセッサディレクティブの一覧を示します。

プリプロセッサ・ディレクティブ

#○○のような形式で記述する命令語をプリプロセッサ・ディレクティブといいます。

プリプロセッサ・ディレクティブは、cファイルやcppファイルをコンパイラに渡す前に処理を実行するため、関数などのオーバーヘッドが発生せず有用に使うことができればかなり効果的に動きます。

全部で14種類あり、それぞれの簡単な説明を下記に示します。

#define 識別子とトークン文字列の関連付けを行い、以降コード中に識別子が見つかるたびに指定したトークン文字列と置換を行う。
#error コンパイル時にユーザー指定のエラーメッセージを出力し、コンパイルを終了する。
#import タイプライブラリーの組み込みを行う。
#undef #defineで作成した識別子を削除します。
#elif #else ifの略。#ifと#else、もしくは#ifと#endifの間に記述可能。
#if 整数定数、文字定数、演算子を記述でき、条件付きコンパイルに使用します。
#include ヘッダーファイルなどのインクルードファイルを組み込みます。
#using

/clrでコンパイルされたプログラムにメタデータをインポートします。

#else  #if/#elifと#else、もしくは#if/#elifと#endifの間に記述可能。
#ifdef  #defineで定義されていればTRUEとなるディレクティブです。
#line  コンパイラが管理する行番号およびファイル名を変更します。
#endif  #ifと対になるディレクティブ。#ifの終わりを示す。
#ifndef  #defineで定義されていなければTRUEとなるディレクティブです。
#pragma

プラグマ ディレクティブは、コンピューター固有またはオペレーティング システム固有のコンパイラ機能を指定します。
キーワードにより、マクロ定義内のプラグマ ディレクティブをコーディングできます。

#define / #ifdef / #ifndef

#defineディレクティブは「識別子とトークン文字列の関連付けをしたり、マクロを作成できる。」ということは前回お話ししました。

上記のように記述すれば、以降ソースコード内に「DEBUG」を見つけると「1」に置換します。

#ifdef

#ifdefと#ifndefは、「識別子が#defineによって定義されているか」を判定します。
よく見るコードでは以下のようなものです。

このようにデバッグ中は識別子「DEBUG」を定義しておき、確認用のメッセージなどをいれることでデバッグがしやすくなります。
リリースの際は「#define DEBUG 1」を削除すれば、コンパイラが「#ifdef DEBUG ~ #endif」を無視してくれるので余分なコードが生成されることもありません。

#ifndef

既になんとなく分かっている方も多いかもしれませんが、#ifndefディレクティブは「DEBUGが定義されていなければ~」という判定を行います。

新しくコードを作成する場合は#ifを使おう

この記事を作成するためにMSDNを見ていると、#ifdefや#ifndefは非推奨とまではいかなくとも、#if, #elif, #endifを使用するようにされていました。

現在は過去のC++との互換性維持のために残されているだけとなっているようですね。
新しくコードを作る際に、同様の動作をさせたい場合は以下のように作成するべきです。

まとめ

MSDNでは#ifとdefined(identifier)を使用するようにと記載されていますが、実際にはまだまだ#ifdef/#ifndefは使われていますし、見る機会もかなり多いと思います。

if文もそうですが入れ子などが複雑になってくると、かなり分かりづらくなりますので急に慌てないようにしっかり理解していなければいけませんね

スポンサーリンク

スポンサーリンク

-C/C++, プログラミング言語

執筆者:

関連記事

【Boost】Boostライブラリの日付を使ってみよう!

先日の記事でBoostをインストールできたのでBoostのライブラリを使って遊んでみましょう。 今回は日付に関する情報をBoostから取得・表示したり、〇月〇日~□月□日が何日間あるか(期間)取得して …

【Boost】boost::property_treeでXMLファイルを書き込もう!

前回の記事でXMLファイルの書き込みは難しくなくできそうでしたネ。 今回はXMLファイルの書き込みを行い、出力してみましょう。 読み込みと同じくライブラリファイルは不要で、ヘッダーファイルのみで利用で …

【MFC】マルチスレッドでプログレスバーを実装しよう その1

実は今回紹介する方法は、もしかしたら正しくないのかもしれません。 ダイアログベースのプログラムで以下の条件を満たし、プログレスバーを表示したいと考えました。 スレッド実行中はモーダルダイアログを表示さ …

【MFC】フォルダー選択ダイアログの表示【Visual C++】

出力先の指定などフォルダー選択のダイアログを表示させたいことがあります。 フォルダー選択ダイアログを表示させるためには、SHBrowseForFolder関数を使います。 SHBrowseForFol …

【OpenCV】OpenCVをビルドして画像処理をしてみよう!

今日はOpenCVを使って画像表示をしてみたいと思います。 ツールやアプリケーションを作る場合、多かれ少なかれ画像処理は必要になってくるのではないでしょうか。 また画像処理関係ではまると泥沼化する場合 …