错误:声明'noreturn'不应返回的函数
error: function declared 'noreturn' should not return
在我的工作场所,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]
}
^
我已经咨询过这个问题,但他们都没有解释上述警告的原因。
1) 编译器是否像这里解释的那样隐式添加了return
?
2) 即使我抛出异常,为什么编译器相信我的函数会返回?
3) noreturn属性提到
当applies:noreturn标记的函数仍然可以通过抛出异常或调用longjmp。
这与我的问题有关吗?
但是你回来了!如果if语句为false,则通过函数末尾的下降返回。您可能知道这种情况永远不会发生,因为m_call_throw()
也不会返回(是吗?),但编译器显然不理解这种逻辑。
m_call_throw()
是否标记为noreturn?如果没有,就添加它。如果编译器没有注意到这一点,你可以在函数的末尾添加一个额外的抛出,你知道这个抛出永远不会到达,但应该会使警告静音。
编译器无法证明函数将始终抛出。这不是一个错误——编译器总是会在某些情况下无法证明这两种情况。
它是否应该警告你是一个有趣的问题。警告意味着它有时会报告不存在的错误;没有警告意味着它有时会错过一个真正的bug。
您可以很容易地使警告不致命,或者通过多种方式使其静音。对此特定文件禁用它,或者在末尾添加对abort
的调用。每种情况都需要权衡,但这就是生活。
如果您可以从lambda/std::函数切换到普通成员函数,只需这样做,并使其成为noreturn
。遗憾的是,不能有noreturn
函数类型、noreturn
std::function
或noreturn
lambda,这是IMHO语言中的一个错误。
这是因为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();
}
现场演示在这里。
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 接收和返回函数指针的函数指针的类型?
- 我的动态链接队列在同一输出流中调用时不正确地输出三个返回函数
- C++函数链返回函数
- 返回函数指针的函数的签名
- 由于值返回函数中的错误,程序无法编译.它说未声明的标识符
- 非常量引用返回函数在常量值返回函数上用作 r 值
- 如何在 C++ 中从 void 返回函数访问变量
- 返回函数中带有 2 个可选 ctor 的对象
- 如何在 c++ 中返回函数的结构向量
- 返回 C++ 函数中的引用
- 使用向量时,当返回函数更改时,无法看到输出
- 如何在递归中使用返回函数
- 返回函数模板的类型C++作为第二个模板参数
- 为什么静态指针返回函数中有一个"静态"键?
- 递归返回函数,在特殊情况下不返回
- 从类返回函数
- 从类成员函数返回函数指针
- 从返回函数中推断不存在的模板参数