预处理器指令在一行内如果

时间:2012-10-02 13:12:38

标签: c compiler-construction

我有这个功能

TOKENP scan_line() {
    TOKENP cur, last = 0;

    while(cur = scan_opd())
        last = cur;

    if (cur = scan_comm())
    #if ENABLE_COMMENT_AS_TOKEN
        add_token(cur);
    #endif
    return last;
}

如果#if指令为false,则将其编译为

if (cur = scan_comm())
    return last;

if (cur = scan_comm());
return last;

2 个答案:

答案 0 :(得分:6)

它将被编译,就好像禁用的行不存在一样,所以:

if (cur = scan_comm())
    return last;

您应该使用大括号来明确您的意思。

if (cur = scan_comm())
{
    #if ENABLE_COMMENT_AS_TOKEN
    add_token(cur);
    #endif
}    
return last;

答案 1 :(得分:0)

它将编译出该代码,因此您的return语句将成为有条件的。含义:

if(cur = scan_comm())
  return last;
格雷厄姆·博兰德,这是正确的,但我想确保你明白问题是什么。看看这个:

int somef(int a)
{
    if(a == 0)
#if something
    a++; 
#endif
    return 0;
}

int main() {
    int a = 3;
    int b = 10;

    b = somef(a); 

    printf("b is %d\n", b);
    ...do more useful stuff with b...

如果使用gcc -Werror -Wall编译此代码,它应该会失败,例如“控制到达非空函数的结尾”。这让你知道代码有问题。

如果你在没有安全选项的情况下进行编译,它可能会在没有警告的情况下通过。现在你认为一切都很好,但是因为在这个示例代码中没有定义代码something,所以代码消失了,我们从函数调用中得不到“0”。在这个特定情况下,b被指定为3.

我们在这里遇到了一些未定义的行为。现在当我用b做“有用的东西”时,期望它原来是0,我将有一个非常很难理解为什么值为“3”。

括号内总是安全的:

if (cur = scan_comm())
    add_token(cur);

return last;

VS

if (cur = scan_comm())
{
    add_token(cur);
}

return last;

这两个都是一样的,但第二个有助于防止愚蠢的错误。