c++ - [[noreturn]] 错误处理程序调用必须返回的函数,仍然收到警告
问题描述
在下面的代码中,两个错误处理程序都声明为[[noreturn]]
,我知道必须返回值的函数调用抛出且永不返回的函数是否是明确定义的行为。
如果控制在f
没有 return 语句的情况下到达函数末尾,那将是未定义的行为,但这是不同的,因为 return 永远不会发生。
// 'function' must return a value
#pragma warning(default:4716)
class Base
{
public:
[[noreturn]] virtual void ErrorHandler()
{
throw 0;
}
int f(int x)
{
if (x > 0)
return x;
else ErrorHandler(); // C4716
}
};
class Derived :
public Base
{
public:
[[noreturn]] void ErrorHandler() override
{
throw 1;
}
};
int main()
{
Base b;
b.f(0);
Derived d;
d.f(0);
}
这仍然是UB
,如果不是,那么为什么我会收到警告?
除了上述问题,我想要一个ErrorHandler
可以处理异常并将控制权返回给调用者的设计,在这种情况下,我如何知道被覆盖的处理程序是否返回?
例如,我们可以删除[[noreturn]]
并假设处理程序可能返回也可能不返回,那么如何设计函数f
?如果参数为零但返回值必须非零,则返回什么?
主要我想摆脱警告并确保行为已明确定义,并且返回值必须为正值,否则函数f
将无法继续。
编辑
如果我们将代码修改为具有非虚拟错误处理程序,则警告消失。
那么是什么让第一个案例引发了警告呢?有什么不同?
class Base
{
public:
[[noreturn]] void ErrorHandler()
{
throw 0;
}
int f(int x)
{
if (x > 0)
return x;
else ErrorHandler(); // OK
}
};
class Derived :
public Base
{
public:
[[noreturn]] void ErrorHandler()
{
throw 1;
}
};
int main()
{
Base b;
b.f(0);
Derived d;
d.f(0);
}
解决方案
[[noreturn]] virtual void ErrorHandler()
只告诉该函数不会返回。
我不强制继承的类“继承”属性。
如果你想强制异常,你可能会返回std::exception_ptr
:
class Base
{
public:
[[noreturn]] virtual std::exception_ptr ErrorHandler()
{
std::make_exception_ptr(0);
}
int f(int x)
{
if (x > 0) {
return x;
} else {
auto eptr = ErrorHandler();
if (eptr) {
rethrow_exception(eptr);
}
throw "nullptr eptr";
}
}
};
class Derived :
public Base
{
public:
[[noreturn]] std::exception_ptr ErrorHandler() override
{
std::make_exception_ptr(1);
// or even
// throw 1;
}
};
推荐阅读
- php - 我将如何回应尚未确认其电子邮件的用户
- compilation - Perl 6 中后缀或后缀之前的点是什么意思?
- postfix - 滥用 - SASL 登录身份验证失败:UGFzc3dvcmQ6
- ios - 如何更新另一个 UIViewController - SWIFT 上的进度视图?
- python-3.x - 使用 pip-python 3.6 安装 flask-pymongo
- assembly - 将 2 个寄存器作为一个移位
- c++ - C++ 代码在 Linux 上按预期工作,但在 Windows 上不工作
- c++ - CMake:从 src 和其他静态库构建共享库
- javascript - 用 Javascript 替换单词而不删除图像
- python - 如何为货币重新训练现有的 spacy NER 模型