无法绕过预处理宏

时间:2016-01-27 12:41:20

标签: c macros conditional-compilation

我仍然在使用C语言中的宏。

所以这个应该返回-2:

#define A
#define C
int main()
{
    int i =
    #ifdef A
    #ifdef B // if A AND B is defined
        -1
    #else    // A is defined AND B is NOT defined
        -2
    #endif
    #else   // A is not defined
        -3
    #endif
    ;
    printf("%d \n", i);
}

为什么这会返回-3然后:

#define B
#define C
int main()
{
    int i =
    #ifdef A
    #ifdef C
        -1
    #else
        -2
    #endif
    #else
        -3
    #endif
    ;
    printf("%d \n", i);
}

在我看来,好像宏有自己的逻辑。

4 个答案:

答案 0 :(得分:1)

override_function()

在你的情况下我将是-2,因为A是定义的但B未定义

答案 1 :(得分:1)

首先让我相应地缩进代码以便于理解。

#define A
#define C
int main()
{
    int i =
    #ifdef A
        #ifdef B
             -1
        #else
             -2
        #endif
    #else
        -3
    #endif
    ;
    printf("%d \n", i);
}

现在,根据#ifdef预处理指令,引用C11标准,章节§6.10.1,

  

表格的预处理指令

# ifdef identifier new-line groupopt<br>
# ifndef identifier new-line groupopt`<br>
     

检查标识符当前是否定义为宏名称。[...]

     

按顺序检查每个指令的条件。如果它的计算结果为false(零),则为该组   跳过它控制的指令:仅通过确定的名称处理指令   该指令是为了跟踪嵌套条件的级别;剩下的   指令的预处理标记被忽略,其他预处理标记也被忽略   组。只有控制条件评估为真(非零)的第一组是   处理。如果没有条件评估为true,并且有#else指令,则   由#else控制的组被处理;缺少#else指令,所有组   直到#endif被跳过。

关于您的代码,

  • #ifdef A为TRUE,
  • #ifdef B为FALSE,因此继续#else部分,-2包含在源代码中。
  • 跳到外#endif

因此,在预处理之后,代码基本上看起来像

int i =-2 ;
printf("%d \n", i);

检查输出,应为-2。

按照相同的逻辑,您可以找到其他代码的预处理输出。

答案 2 :(得分:1)

在第一种情况下,

int i =
#ifdef A
    #ifdef B // if A AND B is defined
        -1
    #else    // A is defined AND B is NOT defined
        -2
    #endif
#else   // A is not defined
    -3
#endif

此处A已定义,但B未定义。因此,最后的else案例将仅被考虑。因此输出将为-2

然而,在第二种情况下,

int i =
#ifdef A
    #ifdef C
        -1
    #else
        -2
    #endif
#else
    -3
#endif

C已定义,但A不再如此,它会转到返回else的最后-3条件。

答案 3 :(得分:1)

让我试着以简单的方式回答。

首先,你是对的宏有自己的逻辑,也许你了解它们是如何预处理器和所有。如果没有,那么预处理器是编译器读取的第一个代码,无论它们出现在源代码的哪个位置。

在编译器检查宏之后,就像你的情况一样,你的普通代码的某些部分对编译器来说是“不可见的”。现在让我们分析一下你的案例中隐藏或不可见代码的方式和内容。

在这种情况下,您使用的是#define A#define C。这类似于布尔(但并不完全),A和B已被声明为'true'或'defined'。

然后使用#ifdef A#ifdef:是if的缩写形式)这里有一个if语句。它检查A是否“已定义”。在你的情况下,A被定义,所以我们继续下一部分,可以看作if语句中的代码。如果这里没有定义A,我们将转到第二个#else // A is not defined

现在我们检查#ifdef B并且没有在您的案例中定义B,因此我们转到后面的第一个#else // A is defined AND B is NOT defined。因此将I的值设置为-2。 #endif就像第二个if语句的结束花括号一样。接下来我们转到第二个#endif,因为A已定义,因此我们不会进入第二个#else

最后你会得到-2的答案。我检查了这段代码,它确实返回-2。