#defineを使うのは代替手段が無い場合のみに抑えたい

C言語及びその派生のC++、Objective-Cでよく使われているマクロとして、#defineがある。これは、特定の文字を別の文字に置き換えるというマクロで、C言語を中心に多重インクルードの防止や定数、インライン展開する関数などにマクロが用いられていた。

個人的にはインクルードガード目的以外では以下の理由で使うのは好ましくないと考えている

まず、型安全ではないことである。基本的に#defineはソースコード内のコードの文字列を置き換えるだけなので、その定義の型を指定できないからである。その点ではconst修飾子付きの変数(定数)やenum、インライン関数などでは単純な文字列の置き換えではないため、型を指定することができ、その点では比較的バグを防ぎやすいと言える。定数の定義では基本的にマクロではなく、const修飾子による定数あるいはenumを使用したい。

最も、C言語では型にとらわれない関数を定義できない1 ため、その点ではマクロによるインライン展開は不可欠となっている。例えば、最大値を取り出す場合は以下のようになるだろう。

[code lang=”c”]#define MAX(a,b)2[/code]

これも、現在のC++ではテンプレートを使用すれば不要である。C++であれば、以下のように書ける。

[code lang=”cpp”]template<typename T> max(T a, T b)
{
return a > b ? a : b;
}[/code]

この点をふまえると、通常の変数(定数)や関数のように使える方がコーディング上好ましいと言える。

なお、多重インクルードについては、Objective-Cでは#importを使う限りはインクルードガードなしでも多重インクルード問題は発生しないこと、マイクロソフト系の処理系を中心に#pragma onceを使用するという手段があるものの、#pragma onceはデファクトスタンダードと化してはいるものの標準仕様ではないため、使用するのはあまり好ましくない。

マクロを使おうとするしあ、それに代わる手段があるかどうか考えて、無い時に限って使うようにしたい。

ウェブマスター。本ブログでITを中心にいろいろな情報や意見などを提供しております。仕事依頼や相談などについては、Contact Formよりお願いいたします。
  1. 例えばint型やdouble型用の変数を別途定義しなければならない []
  2. a) > (b) ? (a) : (b []
スポンサーリンク

フォローする