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

Ambiguous if and else branches: Is the behaviour defined?

本文关键字:定义 是否 分支 if else 不明确      更新时间:2023-10-16

我最近遇到了一些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++程序中看到了这段代码,它似乎更倾向于第一种解决方案。

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

是的,它是有定义的。在C(以及我所知道的所有类似的语言)中,"悬空else"绑定到最后一个自由的if,因此这种解释

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

是正确的。

没有歧义。else子句总是指它所能附着的最近的if。来自c++标准(6.4选择语句):

在子句6中,术语子语句是指在语法符号中出现的包含语句或语句。选择语句中的子语句(每个子语句都是if语句的else形式)隐式地定义了一个局部作用域(3.3)。

如果选择语句中的子语句是单个语句而不是复合语句,就好像它被重写为包含原始子语句的复合语句。(例子:

   if (x) int i;

可以等价地重写为

     if (x) { 
           int i;
     }

这意味着你写的代码可以重写为:

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

定义良好。else总是与最近的可用if配对

它是在c中定义的。一个else总是与最近的if配对;因此,您应该使用适当的大括号来避免歧义。

是的,它不是模棱两可的,因为规则声明它应用在哪里,但是我的GCC c++编译器仍然给出警告,说明它是:

/brainModule/brainModule .cpp:在函数' void failExpiredPendingAndRunning() '中:./brainModule/brainModule .cpp:158:16: 警告:建议显式大括号避免歧义的' else ' [-Wparentheses]if (job->isExpired() == false)

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