其他分享
首页 > 其他分享> > c – 我应该为C函数声明包装器noexcept吗?

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