ぴぐノート

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++, プログラミング言語

執筆者:

関連記事

【OpenCV】MFCのピクチャーコントロールに描画しよう!

前回、OpenCVを使って画像の回転や二値化などを行って動作確認をしました。 今回はMFCでダイアログベースのアプリケーションを作成し、ピクチャーコントロールにOpenCVで読み込んだ画像を表示させて …

【Boost】boost::property_treeの例外処理を考えよう!

ライブラリなどを使用していると、「使い方は大体分かった!使ってみよう!」とすると微妙にはまってしまうことがあります。 前回・前々回でお話しした文字コードもその一つですが今回は例外処理について考えてみま …

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

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

【OpenCV】OpenCVを使ってみよう!表示・回転・拡縮・二値化

前回インストールを行ったOpenCVライブラリを使ってサンプルプログラムをいくつか作成してみましょう。 OpenCVはすごく有名な画像処理ライブラリなのでインターネットで探せばサンプルプログラムはたく …

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

以前はアプリケーションの設定ファイルに単純なテキストである、INIファイルを用いていたアプリケーションも多かったですが、最近はXML(Extensible Markup Language:拡張可能なマ …