Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
If statement 为什么是";“错误”;是否仍要计算ifelse宏的表达式?_If Statement_M4 - Fatal编程技术网

If statement 为什么是";“错误”;是否仍要计算ifelse宏的表达式?

If statement 为什么是";“错误”;是否仍要计算ifelse宏的表达式?,if-statement,m4,If Statement,M4,我编写了一个小型m4脚本(test.m4),用于测试目的: define(`test', `ifelse(`$#', `1', `$1', test(shift($@)))') test(`arg1', `arg2') 并使用m4 test.m4-t test-de1运行它。输出是 m4trace: -1- test -> ifelse(`2', `1', `arg1', test(shift(`arg1',`arg2'))) m4trace: -2- test -> ifelse

我编写了一个小型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(`')))
.
.
.
直到由于超出递归限制而中止执行。我想知道为什么会这样,因为实际上
1
1
应该相等,而
if-else
宏的计算结果应该是
`

但是,我有一个创新的想法,将宏放在引号中,因此宏看起来是这样的:

define(`test', `ifelse(`$#', `1', `$1', `test(shift($@))')')
test(`arg1', `arg2')
瞧,它就像一个符咒(也就是说,
arg2
与一条主要的新行一起打印出来)。
输出(具有相同的调用参数):

NL
代表“换行”)

我的结论是:尽管要比较的两个字符串实际上相等,但预处理器仍然会计算分支

这有什么特别的目的吗?在我看来,这是不直观的。还是我遗漏了什么



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

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

在第一种情况下,
test
宏在父级的
test
的宏替换过程中执行。所以您会经历一个递归:内部测试内部测试等等

第二种情况使表达式随后执行。所以你没有递归。一次又一次的测试

第16.3节“其他不兼容性”:

在这种情况下,禁止宏保留自己的名称将是一个无用的限制。当然,这会留下更多 GNU m4用户上吊的绳索

NL
m4trace: -1- test -> ifelse(`2', `1', `arg1', `test(shift(`arg1',`arg2'))')
m4trace: -1- test -> ifelse(`1', `1', `arg2', `test(shift(`arg2'))')
arg2