不明确的if和else分支:是否定义了行为?

时间:2011-10-04 08:16:15

标签: c++ c

我最近遇到了一些C ++代码,如下所示:

if(test_1)
    if(test_2)
    {
         // Do stuff
    }
    else
       exit(0);

这是不明确的,因为编译器可以将其视为:

if(test_1)
{
    if(test_2)
    {
    }
    else
    {
    }
}

或作为:

if(test_1)
{
    if(test_2)
    {
    }
}
else
{
}

此代码的行为是否根据任何标准(C,C ++)定义?我在VC ++的C ++程序中看到了这个代码,它似乎更喜欢第一个解决方案。

5 个答案:

答案 0 :(得分:12)

  

此代码的行为是否根据任何标准(C,C ++)定义?

是的,已定义。在C(以及我所知道的所有类似语言)中,“悬空其他”与最后一个免费绑定,因此,这种解释

if(test_1)
{
    if(test_2)
    {
    }
    else
    {
    }
}

是对的。

答案 1 :(得分:4)

没有歧义。 else子句始终引用它可以附加到的最接近的if。从C++ standard(6.4选择陈述):

  

在第6节中,术语子语句是指包含在语法表示法中的一个或多个语句。 selection-statement中的子语句(每个子语句,if语句的else形式)隐式定义本地范围(3.3)。

     

如果selection-statement中的子语句是单个语句而不是复合语句,则就好像它被重写为包含原始子语句的复合语句一样。 [例如:

   if (x) int i;
     

可以等效地重写为

     if (x) { 
           int i;
     }

随后您编写的代码可以重写为:

if(test_1)
{
    if(test_2)
    {
        // Do stuff
    }
    else
    {
        exit(0);
    }
}

答案 2 :(得分:1)

定义明确。 else始终与最近的if配对。

答案 3 :(得分:0)

它在C中定义。else始终与最近的if配对; 因此,你应该使用适当的大括号来避免歧义。

答案 4 :(得分:0)

是的,它并不模糊,因为规则说明了它的应用位置,但是我的GCC C ++编译器仍然给出警告,指出它是:

/brainModule/BrainModule.cpp:在函数“ void failExpiredPendingAndRunning()”中: ../brainModule/BrainModule.cpp:158:16:警告:建议使用大括号以避免歧义的“其他” [-括号] 如果(job-> isExpired()==否)

g ++(Raspbian 6.3.0-18 + rpi1 + deb9u1)6.3.0 20170516