理论上,但不是实际上,抛出函数应该被声明为noexcept吗?

j00*_*0hi 21 c++ function noexcept

声明以下函数是否安全,noexcept即使v.at(idx)理论上可以抛出out_of_range异常,但实际上不是由于边界检查?

int get_value_or_default(const std::vector<int>& v, size_t idx) noexcept {
    if (idx >= v.size()) {
        return -1;
    }
    return v.at(idx);
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 15

你对"安全"的定义是什么?如果您在标记为的函数中抛出异常,noexcept或者noexcept(true)您的程序将被终止(标准15.4.9)

每当抛出异常并且搜索处理程序(15.3)遇到函数的最外面的块时,异常规范不允许异常,那么,

  • 如果异常规范是动态异常规范,则调用函数std :: unexpected()(15.5.2),
  • 否则,调用函数std :: terminate()(15.5.1).

只要这是可以接受的那么你就没事了.如果您无法容忍程序终止,那么它就不安全了.

  • 关键是不会抛出任何异常,所以即使程序不能容忍终止,它仍然是安全的,因为它不会调用std :: terminate(). (5认同)
  • @NathanOliver:正如Jonathan在其他地方指出的那样,如果这些访问是不同步的,那么你就会遇到更大的问题,这些问题会掩盖你在这个函数中可能做的任何事情(除了引入同步).这样的努力实际上毫无意义. (5认同)

Mat*_*Sax 9

这很安全.如果发生异常,声明函数noexcept将导致程序立即终止(通过调用terminate()).只要没有抛出异常,一切都很好.


edm*_*dmz 5

我们没有完整的场景来准确确定该函数是否能够抛出异常。


您的假设虽然是正确的:因为您正在做std::vector::at无论如何都会做的事情,所以在给定的情况下它不太可能有害。然而,一般来说,此类函数可能会受到无效因素的影响,因此可能会引发异常。这些可能是线程、进程或信号,它们可能会将执行交错到可能修改的代码std::vector,而这些代码不能安全地处理,也不能std::vector::at

如果您也想考虑这些可能性,您需要有类似的东西

int get_value_or_default(const std::vector<int>& v, size_t idx) noexcept       
{
    try { return v.at(idx); }
    catch (std::out_of_range const& e) { return -1; }
}
Run Code Online (Sandbox Code Playgroud)

  • 正如乔纳森在其他地方指出的那样,如果这些访问不同步,那么您就会遇到更大的问题,这些问题会掩盖您在此函数中可能执行的任何操作(除了引入同步之外)。这样的努力实际上毫无意义。 (4认同)