The primary built-in m4 macro is define(), which is used to define new macros. The following input:
define( name, stuff)
causes the string name to be defined as stuff. All subsequent occurrences of name are replaced by stuff.The defined string must be alphanumeric and must begin with a letter (an underscore is considered to be a letter). The defining string is any text that contains balanced parentheses; it may stretch over multiple lines.
As a typical example
define(N, 100) ... if (i > N)
defines N to be 100 and uses the symbolic constant N in a later if statement.
As noted, the left parenthesis must immediately follow the word define to signal that define() has arguments. If the macro name is not immediately followed by a left parenthesis, it is assumed to have no arguments. In the previous example, then, N is a macro with no arguments.
A macro name is only recognized as such if it appears surrounded by non-alphanumeric characters. In the following example, the variable NNN is unrelated to the defined macro N, even though the variable contains Ns.
define(N, 100) ... if (NNN > 100)
m4 expands macro names into their defining text as soon as possible. So
define(N, 100) define(M, N)
defines M to be 100 because the string N is immediately replaced by 100 as the arguments of define(M, N) are collected. To put this another way, if N is redefined, M keeps the value 100.
There are two ways to avoid this result. The first, which is specific to the situation described here, is to change the order of the definitions:
define(M, N) define(N, 100)
Now M is defined to be the string N, so when the value of M is requested later, the result is always the value of N at that time. The M is replaced by N which is replaced by 100.