2

我有这个功能

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指令为假,它会被编译为

if (cur = scan_comm())
    return last;

或者

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

?

4

2 回答 2

6

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

if (cur = scan_comm())
    return last;

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

if (cur = scan_comm())
{
    #if ENABLE_COMMENT_AS_TOKEN
    add_token(cur);
    #endif
}    
return last;
于 2012-10-02T13:14:28.743 回答
0

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

if(cur = scan_comm())
  return last;

Graham Borland,说得对,但我想确保您清楚问题所在。看看这个:

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;

对比

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

return last;

这两个工作相同,但第二个有助于防止愚蠢的错误。

于 2012-10-02T13:49:25.203 回答