为什么 ifelse 宏的 "wrong" 表达式仍然被求值?
Why is the "wrong" expression of an ifelse macro evaluated anyway?
我写了一个小的 m4 脚本 (test.m4
) 用于测试目的:
define(`test', `ifelse(`$#', `1', `', test(shift($@)))')
test(`arg1', `arg2')
和运行它与m4 test.m4 -t test -de
1。输出是
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', `', `test(shift($@))')')
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
代表"newline")。
我的结论:即使要比较的两个字符串实际上相等,预处理器仍然会评估 [not-equal]
b运行ch。
这有什么特定的目的吗? IMO,这只是不直观。还是我遗漏了什么?
1 -t test
打开宏 test
的调试跟踪。 -de
将调用宏的定义添加到调试输出。
虽然表达式相同(除了引号),但它们的执行时间不同(由于引号)。
在第一种情况下,test
宏在父级 test
的宏替换期间执行。所以你经历了一个递归:test inside test inside test等等。
第二种情况使表达式在AFTERWARDS 之后执行。所以你没有递归。测试后测试。
This behaviour is very well described in the manual.
“16.3 其他不兼容”部分:
In cases like this one, an interdiction for a macro to hold its own name would be a useless limitation. Of course, this leaves more
rope for the GNU m4 user to hang himself!
我写了一个小的 m4 脚本 (test.m4
) 用于测试目的:
define(`test', `ifelse(`$#', `1', `', test(shift($@)))')
test(`arg1', `arg2')
和运行它与m4 test.m4 -t test -de
1。输出是
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', `', `test(shift($@))')')
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
代表"newline")。
我的结论:即使要比较的两个字符串实际上相等,预处理器仍然会评估 [not-equal]
b运行ch。
这有什么特定的目的吗? IMO,这只是不直观。还是我遗漏了什么?
1 -t test
打开宏 test
的调试跟踪。 -de
将调用宏的定义添加到调试输出。
虽然表达式相同(除了引号),但它们的执行时间不同(由于引号)。
在第一种情况下,test
宏在父级 test
的宏替换期间执行。所以你经历了一个递归:test inside test inside test等等。
第二种情况使表达式在AFTERWARDS 之后执行。所以你没有递归。测试后测试。
This behaviour is very well described in the manual.
“16.3 其他不兼容”部分:
In cases like this one, an interdiction for a macro to hold its own name would be a useless limitation. Of course, this leaves more rope for the GNU m4 user to hang himself!