I wrote a small m4 script (test.m4
) for testing purposes:
define(`test', `ifelse(`$#', `1', `$1', test(shift($@)))')
test(`arg1', `arg2')
and ran it with m4 test.m4 -t test -de
1. The output was
m4trace: -1- test -> ifelse(`2', `1', `arg1', test(shift(`arg1',`arg2')))
m4trace: -2- test -> ifelse(`1', `1', `arg2', test(shift(`arg2')))
m4trace: -3- test -> ifelse(`1', `1', `', test(shift(`')))
m4trace: -4- test -> ifelse(`1', `1', `', test(shift(`')))
.
.
.
until execution was aborted due to an exceeded recursion limit. I wondered why this was so because actually 1
and 1
should compare equal and the if else
macro should evaluate to `'
.
However, I had the innovative idea to put the [not-equal]
into quotation marks, so the macro looked like this:
define(`test', `ifelse(`$#', `1', `$1', `test(shift($@))')')
test(`arg1', `arg2')
and voilĂ , it worked like a charm (i.e., arg2
was printed out along with a leading newline).
The output (with the same invocation parameters):
NL
m4trace: -1- test -> ifelse(`2', `1', `arg1', `test(shift(`arg1',`arg2'))')
m4trace: -1- test -> ifelse(`1', `1', `arg2', `test(shift(`arg2'))')
arg2
(NL
stands for "newline").
My conclusion: even though the two strings to compare are, in fact, equal, the preprocessor evaluates the [not-equal]
branch nevertheless.
Does this have any specific purpose? IMO, it's just unintuitive. Or am I missing something?
1 -t test
turns debug tracing for the macro test
on. -de
adds the definition of an invoked macro to the debugging output.