GMSL seq函数的实现
Implementation of the GMSL seq function
GNU Make Standard Library 包含一个 seq
函数。它比较两个字符串和returns形式为$(true)
和$(false)
的布尔值,表示它们是否相等。
用subst
函数实现:
seq = $(if $(subst x,,x)$(subst x,,x),$(false),$(true))
我想了解的是:
为什么要用两个代入判断两个字符串是否相等?
为什么要在两个字符串前加上 x
?
显然是通过评估 x - y = 0
来测试相等性,其中:
- 二进制
-
运算符对应subst
函数
- 两个字符串分别对应
x
和y
变量
0
对应空串,在Make 中逻辑为false
-
是可交换的,所以 x - y = y - x
.
那么,这个函数是在评估 (x - y) + (y - x) = 0
时实现的吗?
看看如果只比较一次会发生什么
seq = $(if $(subst x,,x),false,true)
$(error $(call seq,,xxxxxx))
生成文件:2:*** 正确。停止。
糟糕。
为什么要用两次代换来判断两个字符串是否相等?
处理一个字符串只是另一个字符串重复的情况。因为 $(subst)
将删除所有出现的字符串 seq
如果这样写会非常失败:
seq = $(if $(subst ,,),$(false),$(true))
在测试字符串 aa
和 aaaa
时,因为 $(subst aa,,aaaa)
将是一个空字符串,它会给出答案 $(false)
,但反转字符串和 $(subst aaaa,,aa)
将是 aa
,这将使答案为真。
所以,替换是通过两种方式完成的,以确保当从 </code> 中删除 <code>
时,结果是一个空字符串,反之亦然(我使用 $(subst)
作为这里是减法运算符)。由于 $(if)
的工作方式,两个 $(subst)
本质上是被 AND 运算在一起的(空字符串 == true,因此字符串的连接变为 AND)。
为什么要在两个字符串前加上 x
?
seq
实现如下:
seq = $(__gmsl_tr2)$(if $(subst x,,x)$(subst x,,x),$(false),$(true))
不幸的是,我之前使用 x
的推理似乎已经消失在时间的迷雾中。我怀疑这与 GNU make 经常剥离 whitespace 并且在 $(subst)
whitespace 的情况下被删除有关。查看
的输出
$(subst ,,the quick brown)
注意那里开头的双 space。现在看看
的输出
$(subst e, ,the quick brown)
在第一种情况下,space 被 GNU make 使用,而 $(subst)
什么也没做。在第二种情况下,space 未 消耗。
然而,在我使用 $(subst)
的上下文中,这无关紧要,因为来自 </code> 等变量的 spaces 被保留(即 space剥离发生在扩张之前)。您可以通过以下内容看到:</p>
<pre><code>space :=
space +=
$(subst $(space),,the quick brown)
将单个 space 字符放入 space
,然后使用它从 the quick brown
.
中删除 spaces
所以,我认为 x
是不必要的。
GNU Make Standard Library 包含一个 seq
函数。它比较两个字符串和returns形式为$(true)
和$(false)
的布尔值,表示它们是否相等。
用subst
函数实现:
seq = $(if $(subst x,,x)$(subst x,,x),$(false),$(true))
我想了解的是:
为什么要用两个代入判断两个字符串是否相等?
为什么要在两个字符串前加上
x
?
显然是通过评估 x - y = 0
来测试相等性,其中:
- 二进制
-
运算符对应subst
函数 - 两个字符串分别对应
x
和y
变量 0
对应空串,在Make 中逻辑为false
-
是可交换的,所以 x - y = y - x
.
那么,这个函数是在评估 (x - y) + (y - x) = 0
时实现的吗?
看看如果只比较一次会发生什么
seq = $(if $(subst x,,x),false,true)
$(error $(call seq,,xxxxxx))
生成文件:2:*** 正确。停止。
糟糕。
为什么要用两次代换来判断两个字符串是否相等?
处理一个字符串只是另一个字符串重复的情况。因为 $(subst)
将删除所有出现的字符串 seq
如果这样写会非常失败:
seq = $(if $(subst ,,),$(false),$(true))
在测试字符串 aa
和 aaaa
时,因为 $(subst aa,,aaaa)
将是一个空字符串,它会给出答案 $(false)
,但反转字符串和 $(subst aaaa,,aa)
将是 aa
,这将使答案为真。
所以,替换是通过两种方式完成的,以确保当从 </code> 中删除 <code>
时,结果是一个空字符串,反之亦然(我使用 $(subst)
作为这里是减法运算符)。由于 $(if)
的工作方式,两个 $(subst)
本质上是被 AND 运算在一起的(空字符串 == true,因此字符串的连接变为 AND)。
为什么要在两个字符串前加上 x
?
seq
实现如下:
seq = $(__gmsl_tr2)$(if $(subst x,,x)$(subst x,,x),$(false),$(true))
不幸的是,我之前使用 x
的推理似乎已经消失在时间的迷雾中。我怀疑这与 GNU make 经常剥离 whitespace 并且在 $(subst)
whitespace 的情况下被删除有关。查看
$(subst ,,the quick brown)
注意那里开头的双 space。现在看看
的输出$(subst e, ,the quick brown)
在第一种情况下,space 被 GNU make 使用,而 $(subst)
什么也没做。在第二种情况下,space 未 消耗。
然而,在我使用 $(subst)
的上下文中,这无关紧要,因为来自 </code> 等变量的 spaces 被保留(即 space剥离发生在扩张之前)。您可以通过以下内容看到:</p>
<pre><code>space :=
space +=
$(subst $(space),,the quick brown)
将单个 space 字符放入 space
,然后使用它从 the quick brown
.
所以,我认为 x
是不必要的。