Я написал небольшой скрипт (m4 test.m4
) для целей тестирования:Почему «неправильное» выражение макроса ifelse оценивается в любом случае?
define(`test', `ifelse(`$#', `1', `$1', test(shift([email protected])))')
test(`arg1', `arg2')
и побежал с m4 test.m4 -t test -de
. Выходной сигнал был
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(`')))
.
.
.
до тех пор, пока исполнение не было прервано из-за превышенного предела рекурсии. Я задавался вопросом, почему это было так, потому что на самом деле 1
и 1
должны сравниваться равными, а макрос if else
должен оцениваться в `'
.
Однако, у меня была новаторская идея поставить [not-equal]
в кавычки, так что макрос выглядит следующим образом:
define(`test', `ifelse(`$#', `1', `$1', `test(shift([email protected]))')')
test(`arg1', `arg2')
и вуаля, он работал как шарм (т.е. arg2
был распечатан вместе с ведущая новая линия).
Выходной сигнал (с теми же параметрами Призывании):
NL
m4trace: -1- test -> ifelse(`2', `1', `arg1', `test(shift(`arg1',`arg2'))')
m4trace: -1- test -> ifelse(`1', `1', `arg2', `test(shift(`arg2'))')
arg2
(NL
обозначает "новой строки").
Мое заключение: хотя две строки для сравнения, по сути, равны, препроцессор все равно оценивает ветвь [not-equal]
.
Имеет ли это какую-либо конкретную цель? ИМО, это просто неинтуитивно. Или я чего-то не хватает?
-t test
получается отладить трассировку для макросъемки test
на. -de
добавляет определение выведенного макроса на вывод отладки.