ぴぐノート

Good code is its own best documentation.

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

C++のプリプロセッサの復習をしよう その1

投稿日:

C++を勉強していた時期から苦手だったのがプリプロセッサでした。
インクルートガードに#ifndefやら#defineやら#pragma onceやら…。

C++に限った話ではありませんが、書籍などでは紙面の関係上ソースファイルを大きく分けたりしないためかプリプロセッサの説明などが不十分であるような気もします。

そんな状況の中でも既存のソースコードなどを見ると#if definedや#pragmaが頻繁に登場して本当に辟易することがあります。

今回は復習も兼ねて順番に確認し直そうと思います。

#include

#includeプリプロセッサ・ディレクティブはマクロやクラス定義などが記述されたヘッダーファイルを読み込みます。

上記の構文はどちらも正しいですが、山かっこ形式と引用符形式では囲まれたヘッダーファイルをどの順番で探し出すかが異なります。
基本的にはコンパイラをインストールした際に付属するヘッダーファイルを検索する場合は山かっこ形式を、コンパイルするソースファイルがあるディレクトリにあるヘッダーファイルを検索する場合は引用符形式で指定します。

ざっくり言えば、iostreamなど標準のヘッダーファイルであれば<>(山かっこ形式)を、それ以外のものは””(引用符形式)で指定すれば大体は問題ありません。

#define

#defineディレクティブは本当に利用の幅が広いです。
基本的にはマクロの定義を行うプリプロセッサとなります。

上記のように記載されていれば、コンパイラが「VERSIONと記述された箇所を3.14に置換」します。
つまり、

と記述されれば、VERSIONが3.14に置換され、double型変数piは3.14で初期化されます。

関数形式マクロ

上記のような使い方以外にも#defineの置換はさまざまな場面で利用されます。

プリプロセッサにより、MAX(1, 2)は以下のように置換されます。

結果、コンソールには[ 2 ]と表示されます。

まとめ

この辺りはまだ簡単に思えますが、#defineが曲者です。
#ifdef, #ifndef, #if defined, #if ! defined, #undef, #演算子, ##演算子と羅列したプリプロセッサは全て#defineと関連してきます。

上手く使えればデバッグ作業やコメントアウトなどに非常に便利ですが、便利すぎていろいろなところで出てくるのでしっかり復習していきます!

スポンサーリンク

スポンサーリンク

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

執筆者:

関連記事

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

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

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

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

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

プログレスバーをマルチスレッドを用いた実装について最後の記事です。 引き続き作成の目的は、 スレッド実行中はモーダルダイアログを表示させること。 モーダルダイアログではプログレスバーを表示し進捗が分か …

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

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

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

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