マクロ (コンピュータ用語)

ウィキペディアから無料の百科事典

マクロ (: macro) あるいはマクロ命令 (: macroinstruction) は、計算機科学の分野では、アプリケーションソフトウェアの自動操作のような、プログラミング言語での記述と比較して粒度が大きい処理を記述したり、テキストを別のテキストに置換したり、粒度が大きい命令を粒度の小さい命令(マイクロ命令)に変換したりするための規則または型[要説明]のこと。マクロを記述するコンピュータ言語マクロ言語と言う(言語の無いマクロ機能もある)。また、テキスト等の変換を記述する言語は変換言語と呼ばれる。マクロは「大きい」「巨大な」という意味。

この記事と、マクロ言語の記事は、それぞれに書くべき内容と書かれている内容が混乱している[要説明]。また以下の内容のいくつかは変換言語についてのものである。

プログラムとマクロ[編集]

アセンブラとマクロ[編集]

アセンブリ言語では、機械語の命令と一対一で対応するニーモニックだけを記述できる。その後、アセンブラにマクロ機能を追加したマクロアセンブラが登場した。マクロアセンブラは複数のニーモニックをまとめ、簡略に記述できる。関数のような引数を取ることができる機能があるかどうかは処理系による。

C言語のマクロ[編集]

C言語は、プリプロセッサと呼ばれる、コンパイラがソースプログラムを解釈してオブジェクトプログラムを生成する前に動作するプロセッサ(処理系)を備えている。番号記号#[1]で始まる、プリプロセッサに与える指令のことをプリプロセッサディレクティブと呼び、いくつかのディレクティブが規格で標準化されているほか、固有のディレクティブをサポートするコンパイラも存在する。

ソースプログラムで

#define STRING1 STRING2 

という行を記述すると、プリプロセッサによってコード中のSTRING1STRING2に置換される。これをオブジェクト形式マクロ (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はsendmailautotoolsで設定ファイルなどを生成するために使われている。

TeX のマクロ[編集]

組版処理ソフトウェア TeX では、ユーザーが独自に定義した新しい命令をマクロと呼ぶ。マクロの定義には\newcommand\def などを用いる。

アプリケーションソフトウェアのマクロ[編集]

表計算ソフトをはじめ多くのアプリケーションソフトウェアで、作業を自動化するためのキーボードマクロ機能やマクロプログラミングが利用できる。

キーボードマクロ[編集]

キーボードによる複数の操作を記録し、一度に再生する機能。マウスなど、キーボード以外の別のインターフェイスによる入力を含む場合もある。複雑な処理を繰り返し行う場合、作業を省力化し、操作ミスを減らすことができる。このことは、作業を自動化すると見なすこともできる。VZ Editorでは、キーボードマクロをマクロの一部として利用することができ、マクロをよく理解できない利用者も、引数を変更するだけで大量処理を短時間にできるため有用であった。

脚注[編集]

  1. ^ 文字コードの観点からは「ナンバー」記号であるが、音楽記号のシャープ♯に形が似ていることから、慣例的に「シャープ」と読まれることもある。

関連項目[編集]