C #if 和 #ifdef 中的预处理器 [已关闭]

问题描述 投票:0回答:1

在学习 C 预处理器

#if
时,我遇到了这个特定的语句,在 GCC 站点上给出的语法中描述了术语表达式,语法:

#if *expression*
    controlled text
#endif

在上述语法中描述的表达式的上下文中,以下语句意味着什么?

声明:在C语言中,表达式可以包含非宏的标识符,这些标识符都被视为数字零。如果您知道 MACRO 在定义时将始终具有非零值,则这允许您编写

#if MACRO
而不是
#ifdef MACRO
。在没有函数调用括号的情况下使用的类似函数的宏也被视为零。

在某些情况下,这种捷径是不可取的。这 -Wundef 选项会导致 GCC 在遇到不是

#if
中的宏的标识符时发出警告。

c
1个回答
0
投票

在 C 中,表达式可能包含非宏的标识符,这些标识符都被视为数字零。

这意味着,如果您有

#if
指令,例如:

#if X == 3

X
未定义为预处理器宏,则将其替换为
0
,因此该指令将被处理为:

#if 0 == 3

这是标准的 C 行为。 GCC 的

-Wundef
选项要求编译器在发生这种情况时发出警告。

有一个例外;标识符

defined
经过特殊处理。如果
defined identifier
defined (identifier)
出现在
#if
指令中,则根据
identifier
是否是定义的宏,将其替换为 1 或 0。

这允许您写

#if MACRO
而不是
#ifdef MACRO
,如果您知道 MACRO 在定义时将始终具有非零值。

由于上述替换,如果

#if MACRO
是已定义的类对象宏,则
#if replacement
将变为
MACRO
,否则将变为
#if 0
。那么我们有以下几种情况:

  • MACRO
    是一个类似对象的宏,可扩展为非零值:
    #if MACRO
    将其评估为 true,而
    #ifdef MACRO
    将其条件评估为 true。
  • MACRO
    是一个类似对象的宏,可扩展为零:
    #if MACRO
    将其评估为 false,而
    #ifdef MACRO
    将其条件评估为 true。
  • MACRO
    未定义为类似对象的宏:
    #if MACRO
    变为
    #if 0
    并被评估为 false,并且
    #ifdef MACRO
    评估其条件为 false。

因此,如果

#if MACRO
不是值为零的表达式,则
#ifdef MACRO
MACRO
的行为相同。

注意:类似对象的宏没有参数,如下所示:

#define MACRO (3+4)

并且类似函数的宏具有参数,如下所示:

#define MACRO(x) (3+(x))

在没有函数调用括号的情况下使用的类似函数的宏也被视为零。

如果

MACRO
被定义为类似函数的宏,则在
#if MACRO
中,不执行宏替换。这是因为类函数宏只有在后面跟有括号时才会被替换,如
#if MACRO(3)
中所示。因此,在宏替换被拒绝后,它继续用
0
替换标识符,变成
#if 0

© www.soinside.com 2019 - 2024. All rights reserved.