在我的工作场所,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]
}
^
我已经咨询了this和this的问题,但没有人解释上述警告的原因。
1)编译器是否按照here解释隐式添加return
?
2)即使我抛出异常,为什么编译器会相信我的函数会返回?
noreturn关键字在此时不会影响异常路径 适用:noreturn-marked功能可能仍会返回给调用者 抛出异常或调用longjmp。
这与我的问题有关吗?
答案 0 :(得分:7)
但你确实回来了!如果if语句为false,则通过函数结尾的下降返回。您可能知道这种情况永远不会发生,因为m_call_throw()
永远不会返回(是吗?),但编译器显然不理解这种逻辑。
m_call_throw()
是否标记为noreturn?如果没有,请添加它。如果编译器没有接受,你可以在函数结尾处添加一个额外的抛出,你知道它永远不会到达但是应该使警告静音。
答案 1 :(得分:1)
编译器无法证明函数将始终抛出。这不是一个错误 - 总会有编译器无法证明这种情况的情况。
它是否应该警告你是一个有趣的问题。警告你的意思是它有时会报告一个不存在的错误;不警告你意味着它有时会错过一个真正的错误。
您可以轻松地使警告不致命,或以多种方式使其静音。禁用此特定文件,或在结尾处添加对abort
的调用。在每种情况下都要做出权衡,但这就是生命。
如果可以从lambda / std :: function切换到普通成员函数,只需这样做,然后将其设为noreturn
。唉,你不能拥有noreturn
功能类型或noreturn
std::function
或noreturn
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。