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

问题描述

我正在编写一个模拟器,并且希望它与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而言是不允许的)检查给定的 identifier 已定义。标识符以字母或下划线开头,并且仅包含字母,下划线或数字。

hi是一个标识符。

(hi)不是。

,

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

...可能包含形式为一元的运算符

defined 标识符

defined ( 标识符 )

,如果当前将标识符定义为宏,则结果为1 名字...

因此,defined的操作数不是通用的C表达式,而是仅 identifier ”或“ ( identifier )”。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...