C++ 一个只能由于整数溢出而失败的函数是否应该不例外?

C++ 一个只能由于整数溢出而失败的函数是否应该不例外?,c++,c++17,integer-overflow,noexcept,C++,C++17,Integer Overflow,Noexcept,完整的问题符合标题。下面是一个简单的例子: constexpr int increment(int const value) /*noexcept?*/ { return value + 1; } 据我所知,noexcept在决定是否用它标记函数时应解释为“nofail”。因此,throwing的任何可能情况都不是必须考虑的唯一理由 我没有使用C++20,因此尚未定义签名溢出。:) 据我所知,noexcept应该被解释为“nofail” 那是不对的noexcept字面意思是“我保证这个函数

完整的问题符合标题。下面是一个简单的例子:

constexpr int increment(int const value) /*noexcept?*/ {
  return value + 1;
}
据我所知,
noexcept
在决定是否用它标记函数时应解释为“nofail”。因此,
throw
ing的任何可能情况都不是必须考虑的唯一理由

我没有使用C++20,因此尚未定义签名溢出。:)

据我所知,noexcept应该被解释为“nofail”

那是不对的
noexcept
字面意思是“我保证这个函数永远不会抛出异常”。还有无数其他类型的失败,比如分段错误、非法指令、调用纯虚拟函数、整数除以零,更不用说了“会计部的鲍勃告诉我,我们所有的客户号码都是由数字组成的,但我刚刚发现我们的第一个客户的ID实际上是Q001,它没有解析。“这些都不会导致异常,也不会有整数溢出,因此,即使在这些代码失败的情况下,除了之外,函数仍然可以是<代码> NOTE,即使它们可以失败,也就是不能抛出C++异常。
然后,您可能会想,“如果一个
noexcept
函数抛出异常会发生什么?”在这种情况下,将调用
std::terminate()
,程序将结束。

noexcept
只是您的“承诺”,即该函数永远不会允许异常从中逃逸,这意味着,如果发生这种情况,您的代码将立即停止,方法是调用
std::terminate
,而不是允许异常转义

知道函数永远不会抛出异常,编译器就可以在调用者中生成更高效/紧凑的代码,并创建更健壮的软件(如果一个软件在没有被设计来处理的事情发生时立即终止,那么它比那些一直在做随机事情的软件更健壮……这是许多年轻程序员都感到困惑的事情)

<> >不幸的是,C++中的异常并不是唯一的失败源,在这里你有一个大的“不确定行为”,所以在C++中编写真正的健壮软件是一项非常困难的任务,因为你还应该避免每一个潜在的未定义行为。(这几乎是不可能做到的;例如,可以生成未定义的行为—任何整数数学运算、任何迭代器的使用、任何数组访问、任何指针访问、任何未初始化的变量、对同一内存的任何多个未排序的副作用、任何竞争条件……等等)

当然,请注意,即使是一种完全“安全”的低级语言,它没有未定义的行为,但有保证的运行时错误,也不是编写真正健壮的软件的“灵丹妙药”。原因是您可以有某种“未定义的行为”如果您的算法没有按照您希望的方式处理呈现给他们的所有案例,那么在更符合逻辑的级别上

换句话说,如果你的程序因为C++的未定义的行为而做了随机的事情,或者因为你捕获和处理了一个不在你认为是来自于(你的代码< >什么代码> >代码>保护你的异常),那么最终用户就没有什么区别了。或者因为您的代码根本没有考虑和处理客户联系数据可能有空电话号码。
未定义的行为概念当然是不好的,之所以存在是因为允许生成更快的代码。在我看来,这应该是编程语言中的默认值,这是有争议的;其他语言更喜欢更安全的默认环境,而是允许特别标记为“快速和危险”的要求程序员从不犯低级错误的区域。

noexcept说明符只是说该函数不会引发异常,其他什么都不会。只要失败模式不引发异常,它仍然可以“失败”或具有未定义的行为。@Someprogrammerdude一些资源(包括StackOverflow)可能不同意您的意见,我相信。例如:。从接受的答案来看:“标准关于
noexcept
…”的政策(我的重点)。这是标准库的策略,而不是强制执行或必须盲目遵循的策略。@Someprogrammerdude是的,而且该策略似乎非常合理。例如,它允许我添加
if(value==INT_MAX){throw Smth{};}
有一天。是的,有一天你可能会想添加类似的东西。但是,在你添加之前,为什么不将它标记为
noexcept
?如本文所述,它可以帮助编译器,但它也是其他程序员读取和推断信息的接口的一部分。如果他们看到你的函数是
noexcept
,那么他们可以使用它在它们自己的
noexcept
函数中,或者不必担心异常,也不需要函数的
try…catch
子句。但是,
std::vector::operator[]
不是
noexcept
,尽管它从不抛出。为什么?@通过:可以预见,有一个这样的问题:是的,那里的观点似乎与答案中的观点相矛盾。@passing\u通过:由于你使用了“应该”一词,也许你的问题没有具体说明和/或基于观点事实上,你不清楚你是否在C++程序中对通用的实践提出了质疑。@ PasigIGIN:定义标准库时所使用的做法是不常见的。他们努力避免对执行者更喜欢做什么的假设,什么样的硬件?E代码将运行,用户代码可以定义什么标识符等等。很多这些事情与大多数C++代码无关,因为我们可以(和)做更多与我们特定的应用程序相关的假设。