c-使用定义的运算符时,双嵌套圆括号在宏内部引发错误



我正在编写一个模拟器,我希望它与C中的宏完全一样。以下代码让我感到困惑:


这是有效的代码,返回true:

#if ((((1 + ((2)))))) == 3

这也是有效的代码,并返回true:

#define hi hello
#if defined (hi)

但这将抛出一个错误并且无法编译:

#define hi hello
#if defined ((hi))

这不起作用有什么特殊原因吗?它似乎应该起作用。


如果您想在线测试宏,这里有一个链接:https://godbolt.org/(将-E作为参数(
这里有一个解释定义运算符的链接:https://gcc.gnu.org/onlinedocs/gcc-8.4.0/cpp/Defined.html

#if进行数学评估。括号的计算结果为C表达式。越多越好,它们不会将表达式计算的值更改为(当然,当设置为更改运算符优先级时除外(。

#ifdef identifier/#if defined identifier/#if defined( identifier )(括号对于defined运算符是可选的,对于#ifdef是不允许的(检查是否定义了给定的标识符。标识符以字母或下划线开头,并且仅包含字母、下划线或数字。

hi是一个标识符。

(hi)不是。

C 2018 6.10.1指定#if#elif指令中define的行为。它说控制条件包含的表达式:

…可能包含形式的一元运算符表达式

defined标识符

defined(标识符)

如果标识符当前被定义为宏,则其求值为1名称…

因此,defined的操作数不是通用的C表达式,而是">标识符"或"(标识)"。