【问题标题】:error: function declared 'noreturn' should not return错误:声明为“noreturn”的函数不应返回
【发布时间】:2016-12-01 03:33:34
【问题描述】:

在我的工作场所,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 标记的函数仍然可以通过以下方式返回给调用者 抛出异常或调用 longjmp。

这与我的问题有关吗?

【问题讨论】:

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


【解决方案1】:

但你确实回来了!如果 if 语句为假,则返回函数末尾。你可能知道这永远不会发生,因为m_call_throw() 也永远不会返回(是吗?),但编译器显然不理解这个逻辑。

m_call_throw() 是否标记为 noreturn?如果没有,请添加它。如果编译器没有注意到这一点,您可以在函数末尾添加一个额外的 throw,您知道它永远不会到达,但它应该使警告静音。

【讨论】:

    【解决方案2】:

    编译器无法证明函数总是会抛出异常。这不是一个错误——总会有编译器无法证明任何一种方式的情况。

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

    您可以轻松地使警告变为非致命警告,或通过多种方式使其静音。为此特定文件禁用它,或在末尾添加对abort 的调用。在每种情况下都需要权衡取舍,但这就是生活。

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

    【讨论】:

    • +1 用于添加我们(还)不能拥有 noreturn 函数类型或 noreturn std::function 或 noreturn lambda
    【解决方案3】:

    那是因为你的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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-04
      • 2015-02-24
      • 1970-01-01
      • 2014-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-15
      相关资源
      最近更新 更多