错误:声明的功能' noreturn'不应该返回

时间:2016-07-27 08:24:13

标签: c++ c++11 gcc lambda

在我的工作场所,noreturn属性的内部名称不同。假设它是INTERNAL_DONT_RETURN

我正在编写一个类的成员函数,我在这里执行类似

的操作
INTERNAL_DONT_RETURN void foo() const
{
    if(!*this)
    {
       throw CoolException();
    }
    m_call_throw();
}

这个m_call_throw()是一个私有类成员std::function<void()>m_call_throw,它作为lambda填充在类的构造函数中。这个lambda什么也没做,只有

m_call_throw([uncoolID]() { throw UncoolException(uncoolID); })

现在两者,gcc-4.9.3和clang都给了我以下警告

error: function declared 'noreturn' should not return [-Werror,-Winvalid-noreturn] } ^

我已经咨询了thisthis的问题,但没有人解释上述警告的原因。

1)编译器是否按照here解释隐式添加return

2)即使我抛出异常,为什么编译器会相信我的函数会返回?

3)noreturn attribute提及

  

noreturn关键字在此时不会影响异常路径   适用:noreturn-marked功能可能仍会返回给调用者   抛出异常或调用longjmp。

这与我的问题有关吗?

3 个答案:

答案 0 :(得分:7)

但你确实回来了!如果if语句为false,则通过函数结尾的下降返回。您可能知道这种情况永远不会发生,因为m_call_throw()永远不会返回(是吗?),但编译器显然不理解这种逻辑。

m_call_throw()是否标记为noreturn?如果没有,请添加它。如果编译器没有接受,你可以在函数结尾处添加一个额外的抛出,你知道它永远不会到达但是应该使警告静音。

答案 1 :(得分:1)

编译器无法证明函数将始终抛出。这不是一个错误 - 总会有编译器无法证明这种情况的情况。

它是否应该警告你是一个有趣的问题。警告你的意思是它有时会报告一个不存在的错误;不警告你意味着它有时会错过一个真正的错误。

您可以轻松地使警告不致命,或以多种方式使其静音。禁用此特定文件,或在结尾处添加对abort的调用。在每种情况下都要做出权衡,但这就是生命。

如果可以从lambda / std :: function切换到普通成员函数,只需这样做,然后将其设为noreturn。唉,你不能拥有noreturn功能类型或noreturn std::functionnoreturn lambda,这是恕我直言的语言中的一个错误。

答案 2 :(得分:0)

那是因为您的foo返回,或者至少似乎返回

当用noreturn声明一个函数时,该函数不能返回:

void Foo() __attribute__((noreturn));

void Foo()
{
    // The application will exit, without returning.
    exit(0);
}

int main()
{
    Foo();
}

您知道您的m_call_throw也不会返回,但编译器不会返回。

因此明确地告诉编译器它可能没有帮助,如下所示:

void Foo() __attribute__((noreturn));
void m_call_throw() __attribute__((noreturn));

void Foo()
{
    // Ok, no return huh?
    m_call_throw();
}

现场演示是here