マクロ (英: macro) あるいはマクロ命令 (英: macroinstruction) は、計算機科学の分野では、アプリケーションソフトウェアの自動操作のような、プログラミング言語での記述と比較して粒度が大きい処理を記述したり、テキストを別のテキストに置換したり、粒度が大きい命令を粒度の小さい命令(マイクロ命令)に変換したりするための規則または型[要説明]のこと。マクロを記述するコンピュータ言語をマクロ言語と呼ぶ。また、テキスト等の変換を記述する言語は変換言語と呼ばれる。マクロは「大きい」「巨大な」という意味のギリシア語: μακροに由来する。
プログラムとマクロ
アセンブラとマクロ
アセンブリ言語では、機械語の命令と一対一で対応するニーモニックだけを記述できる。その後、アセンブラにマクロ機能を追加したマクロアセンブラが登場した。マクロアセンブラは複数のニーモニックをまとめ、簡略に記述できる。関数のような引数を取ることができる機能があるかどうかは処理系による。
C言語のマクロ
C言語は、プリプロセッサと呼ばれる、コンパイラがソースプログラムを解釈してオブジェクトプログラムを生成する前に動作するプロセッサ(処理系)を備えている。番号記号#
[1]で始まる、プリプロセッサに与える指令のことをプリプロセッサディレクティブと呼び、いくつかのディレクティブが規格で標準化されているほか、固有のディレクティブをサポートするコンパイラも存在する。
ソースプログラムで
という行を記述すると、プリプロセッサによってコード中のSTRING1
はSTRING2
に置換される。これをオブジェクト形式マクロ (object-like macro) と呼ぶ。また、
#define SQUARE(val) ((val)*(val))
のようにパラメータをとる関数形式マクロ (function-like macro) を定義することもできる。そのほか、
#define TO_STRING(symbol) #symbol
#define PASTE_TOKEN(a,b) a##b
といった、シンボルの文字列化やトークンの連結を行なうことのできるマクロ特有の演算子も用意されている。マクロによる置換は、文字列リテラルやコメントの中には適用されない。
関数マクロには、引数の型を固定しない、呼び出しの実行時処理コストがかからないなど、関数よりも便利な面がある。しかし、マクロ自体はテキストの置換を機械的に実行するものでしかないので、そのマクロを使用する際にパラメータとしてインクリメント式やデクリメント式を直接渡したり、あるいはパラメータに関数の戻り値を使うために関数呼び出しを直接記述したりすると、それらの評価が意図せず複数回実行される場合がある。これをマクロの副作用と呼ぶ。マクロ利用者が副作用を期待していない場合は、関数マクロの定義時や使用時には注意すべきである。こうした点から、MISRA Cでは関数マクロ機能をできるだけ使わないようにすべきとしている。
なお、「定義済みマクロ」として、コンパイル環境によって特定の値(文字列)に展開されるマクロがある。デバッグのためにプログラム中にファイル名や行番号を自動的に埋め込んだり、前方互換性かつ/または後方互換性および移植性を維持するためにコンパイラのバージョンやターゲット環境(プラットフォーム)によってコンパイルするコードを変更したりする目的で利用する。
C++ のマクロ
C++ではC言語のプリプロセッサマクロも依然として使用可能だが、C++にはテンプレートというマクロの発展系機能が存在する。テンプレートはプリプロセッサではなくコンパイラが解釈・展開する機能であり、マクロと比較して、より言語に密着した能力や型安全性を持つ。また、マクロは名前空間を使うことができず、そのため大規模開発時に意図しない名前衝突により破綻する危険性があるが、テンプレートは名前空間を利用することが可能であり、大規模開発にも向いている。MISRA C++ では問題点の多いマクロよりも安全なテンプレートやインライン関数オーバーロードなどを使用することを推奨している。
しかし、テンプレートではなくマクロでなければ記述できない処理もある。例えばBoost C++ライブラリにおけるBoost.Preprocessorなどのマクロを駆使したライブラリがある。マクロおよびテンプレートは、いずれも静的ダックタイピングによく利用される。プリプロセスあるいはコンパイル時点にコードが決定されるので、マクロやテンプレートを活用したプログラミングは一種のメタプログラミングである。
Lisp のマクロ
Lisp のマクロ処理は、Lisp のプログラム自体が Lisp のリストオブジェクトで表現されるもの(S式)であることを利用し、S式をS式に変換する関数により行われるものであり、この節の他のマクロ(C++のテンプレートを除く)がテキストベース(トークンベースを含む)であるのに対し、テキストベースではない変換系である点で全く異なったものである。プログラムが実行される前に自由に構文木(S式)を操作できるため、Lisp では(他の言語におけるキーワードに相当する)特殊形式も、利用者が自由に追加変更できるという特徴となっている(なお、一部の Lisp にあるリードマクロは読み込み時に働くため、より言語をカスタムする自由度が大きい)。
Lisp でのマクロについては以下の書籍が参考になる。
マクロプロセッサ
m4など、単独のマクロプロセッサもある。m4はsendmailやautotoolsで設定ファイルなどを生成するために使われている。
TeX のマクロ
組版処理ソフトウェア TeX では、ユーザーが独自に定義した新しい命令をマクロと呼ぶ。マクロの定義には\newcommand
や \def
などを用いる。
アプリケーションソフトウェアのマクロ
表計算ソフトをはじめ多くのアプリケーションソフトウェアで、作業を自動化するためのキーボードマクロ機能やマクロプログラミングが利用できる。
キーボードマクロ
キーボードによる複数の操作を記録し、一度に再生する機能。マウスなど、キーボード以外の別のインターフェイスによる入力を含む場合もある。複雑な処理を繰り返し行う場合、作業を省力化し、操作ミスを減らすことができる。このことは、作業を自動化すると見なすこともできる。VZ Editorでは、キーボードマクロをマクロの一部として利用することができ、マクロをよく理解できない利用者も、引数を変更するだけで大量処理を短時間にできるため有用であった。
テキストエディタにおけるマクロ
多くのテキストエディタにキーボードマクロやマクロ言語などのマクロ機能がついている。マクロ機能と正規表現を駆使すれば、高度なテキスト処理を少ない手間で行うことが可能になる。
オフィススイートにおけるマクロ
その他のアプリケーションにおけるマクロ
OSのマクロ
脚注
関連項目