是否有任何m4语法等同于这个C预处理器?
#if defined A || defined B
do something
#endif
简短的回答是否定的。
长答案:
检查是否定义了宏
define(`defined', `ifelse($1()$1, `$1()$1', ``0'', ``1'')')
ifelse(eval(defined(`A') || defined(`B')),
1,
``At least one is defined'',
``Neither are defined'')
在m4中没有合理的方法来检查定义的宏,所以你必须求助于上面的hack。
工作原理
ifelse
检查两个字符串是否相等。在defined
宏中,我在$1
中扩展了两次宏(一次是$1()
,一次是$1
)。我将它与$1()$1
作为字符串进行比较,所以如果它不展开,那么它将比较为真。以两种不同的方式指定宏的原因是因为A
可以定义为``A''
或``A()''
,否则在使用此方法检查是否定义时将导致假阴性。
然后,我在eval
中使用defined
宏来将||
逻辑放在顶部。
警告
- 如果你已经在你的文档中使用了
defined
这个词,你可能想给宏一个不同的名字。 -
defined
宏将不工作宏定义为扩展为无引号语法标记,如(
,,
,或)
。 - 如果要检查的宏是无限递归的,
defined
检查也将永远不会返回。(从本质上讲,要意识到这样的黑客实际上仍然在执行宏。)
虽然最后两点是您期望从宏的ifelse
检查中得到的东西,但是期望从一个宏中检查是否定义了另一个宏可能并不直观。
更好的方法
我更愿意建议你先用一些默认值来定义变量,这样就可以避免检查它是否被完全定义的问题了。
这更容易做到:
# Define this right off the bat:
define(`A', ``0'')
# Maybe later this line will come up...
# Quotes around the A are mandatory
define(`A', ``1'')
# Then soon after that, you can check:
ifelse(A, `0', , ``hey, A is nonzero!'')