c – 我应该为C函数声明包装器noexcept吗?
作者:互联网
假设你有一个只调用C函数的C函数,比如
int ClearTheBin()
{
int result = SHEmptyRecycleBinW(
nullptr,
nullptr,
SHERB_NOCONFIRMATION |
SHERB_NOPROGRESSUI |
SHERB_NOSOUND);
if (SUCCEEDED(result) ||
result == E_UNEXPECTED) // Already empty
{
return 0;
}
return result;
}
显然有一个zillion different things可能会出现对C函数调用的错误,但由于C缺少异常,因此这些错误将存储在生成的代码中.我的问题是:这些函数是否应声明为noexcept?即使该方法不能抛出,也可能给读者一个错误的印象:“这个功能没有什么可以出错,我可以认为它是100%可靠的”,因为这通常是noexcept功能所暗示的.
你对此事有何看法?
解决方法:
“Nothing can go wrong with this function and I can assume it’s 100%
reliable”
我不会那么快地假设.通常,如果我看到一个标记为noexcept的函数,我倾向于寻找可以给我错误的替代方法,如布尔状态,某种全局错误检索函数,成功/失败返回值,类似的东西.只有缺乏这一点,并且可能面对不会产生副作用的功能,我才能做出这样的假设.
在你的情况下,你得到了整个错误代码类型的功能,所以很明显一眼看到界面文档应该告诉我事情可能会出错,但noexcept告诉我这些例外情况不会(或至少不应该以异常的形式向我(呼叫者)报告.
应用noexcept
一般来说,安全方面不愿意使用noexcept.比如std :: string到该函数的单个引入,现在它可以抛出,只有noexcept会把它变成终止而不是我们可以捕获的东西.保证函数永远不会抛出接口/设计级别是一个很难确保实际混合C代码的任何东西,特别是在任何随机同事可能引入的团队设置中(可能在紧急日)一些随机的C函数调用或者可以抛出此功能的对象.
无法投掷
在某些情况下,实际上很容易做出这种保证.一个例子是一个noexcept函数,它有自己的try / catch块,函数所做的一切都包含在其中.如果捕获到异常,请将其转换为某种错误代码并返回该异常.在这些情况下,try / catch保证函数将吞下异常并且不会泄漏到外部世界.这里很容易应用noexcept,因为函数不能抛出.
无法正确投掷
noexcept不需要太多考虑的另一个例子是在函数的情况下,如果抛出则应该被认为是破坏的.一个示例是一个API函数,它跨SDK的模块边界调用,旨在允许使用任何编译器构建插件.因为我们不应该跨越模块边界,特别是在这种情况下,抛出已经是UB并且不应该完成.在这种情况下,noexcept可以很容易地应用,因为按照设计,函数的正确行为永远不应该抛出.
如有疑问,请将其删除.
在你的情况下,如果有疑问,我建议不予理会.你可以通过使用noexcept并且无意中抛弃函数并终止程序来解决更多错误.一个例外是,如果你能够确保这个ClearTheBin函数总是只使用C,没有操作符new(或者至少只是nothrow版本),没有dynamic_casts,没有标准的lib等,这是一个例外.等等.安全方面,除非你能为现在和将来做出这种硬接口级保证.
标签:c-3,noexcept,c,c11,exception 来源: https://codeday.me/bug/20190829/1761784.html