if-statement - 为什么无论如何都要评估 ifelse 宏的 "wrong"表达式?

标签 if-statement m4

我写了一个小的 m4 脚本( test.m4 )用于测试目的:

define(`test', `ifelse(`$#', `1', `$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(`')))
.
.
.

直到由于超出递归限制而中止执行。我想知道为什么会这样,因为实际上 11应该比较相等和 if else宏应评估为 `' .

然而,我有一个创新的想法把 [not-equal] 加引号,所以宏看起来像这样:
define(`test', `ifelse(`$#', `1', `$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 代表“换行符”)。

我的结论:即使要比较的两个字符串实际上相等,预处理器也会评估 [not-equal] 尽管如此,分支。

这有什么特定目的吗? IMO,这只是不直观。或者我错过了什么?

1 -t test为宏打开调试跟踪 test在。 -de将调用的宏的定义添加到调试输出中。

最佳答案

虽然表达式是相等的(除了引号),但它们的执行时间不同(由于引号)。

第一种情况 test宏在父项的宏替换期间被执行 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!

关于if-statement - 为什么无论如何都要评估 ifelse 宏的 "wrong"表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36815971/

相关文章:

text - 如何在pandoc中为每个组成文件分别重新定义-top-level-division?

m4 - 有没有办法使用 m4 包含包含文件中的行子集?

macros - m4 扩展里面的宏

c++ - 当条件激活时停止 arduino 循环

PHP - "if"中的 "while"问题以交替 html 表格行颜色

ios - 如何对 if-else 条件进行更优化的编码?

if-statement - 批处理 - 用户输入到命令提示符(IF 语句问题)

java - 为什么这些字符串不匹配?

m4 - 如何定义接受可变参数的 M4 宏?