基本となる組み込み m4 マクロは、define() です。このマクロを使用して、新しいマクロを定義します。以下を入力すると、文字列 name が stuff として定義されます。
define( name, stuff)
この定義以降に現われる name は、すべて stuff に置換されます。定義される文字列は、英数字にしてください。また、定義文字列の先頭は英数字 (下線は英数字とみなされます) にする必要があります。定義文字列は、1 組の括弧を含んだ任意のテキストです。この定義文字列は複数の行に渡っていても構いません。
典型的な例を以下に示します。
define(N, 100) ... if (i > N)
この例では、N は 100 として定義されており、その定数 N が if 文で使用されています。
前述のように、define() が引数を持っていることを示すには、ワード define の直後に左括弧を置く必要があります。マクロ名の直後に左括弧が続いていない場合は、そのマクロは引数を持っていないとみなされます。したがって、上記の例の N は、引数を持たないマクロです。
マクロ名は、英数字以外の文字で囲まれている場合にだけ、そのマクロ名として認識されます。以下の例では、変数 NNN に N が含まれていますが、定義されたマクロ N とこの変数の間には何の関係もありません。
define(N, 100) ... if (NNN > 100)
m4 は、できるかぎり早くにマクロ名を定義されているテキストに展開します。したがって、以下の例では、define(M, N) の引数を収集するときには N が 100 に置換されているので、M は 100 として定義されます。別の見方をすれば、N を再定義しても M の値は 100 のまま変わらないということになります。
define(N, 100) define(M, N)
このような結果を回避する方法は 2 つあります。1 つは、定義の順序を変更して回避する方法です。この方法は、上記の例のような場合に特に有効です。
define(M, N) define(N, 100)
これにより、M は文字列 N として定義されるので、M の値が後で要求されたときには、結果は常にその時点の N の値になります。つまり M は、N の値 100 に置換されます。