简体   繁体   English

浮点乘法可以在C ++中抛出异常吗?

[英]can floating point multiplication throw an exception in C++?

Is this possible? 这可能吗? I don't think it is, but I don't know if this is something the standard would say, or if it's implementation defined? 我不认为是,但我不知道这是标准会说的,还是它的实施定义? I'm asking because I'm wondering whether it's safe or worth it to mark a constexpr function like this noexcept 我问,因为我想知道是否安全或者值得标记一个constexpr函数,比如noexcept

EX: EX:

constexpr double to_meters(double y) noexcept? {
  return y * 10;
}
constexpr double x = to_meters(y); // Clang-Tidy warns about possible exception without noexcept

No, float point multiplication will normally not throw a C++ exception. 不,浮点乘法通常不会抛出C ++异常。

But think about this: How can clang-tidy possibly know whether to_meter will throw an exception? 但请想一想:clang-tidy怎么可能知道to_meter是否会抛出异常? In C++ every function can throw an exception unless it is explicitly declared not to throw. 在C ++中,除非明确声明不抛出,否则每个函数都会抛出异常。

So clang-tidy has two options: It could do expensive (possibly inconclusive) control flow analysis or it can simply rely on you correctly declaring nothrow , which it does : 所以clang-tidy有两个选择:它可以做昂贵的(可能是不确定的)控制流分析,或者它可以简单地依赖于你正确地声明nothrow它做了

  Finder->addMatcher(
      varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
              unless(hasAncestor(functionDecl())),
              anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(
                        cxxConstructorDecl(unless(isNoThrow())).bind("func")))),
                                         //^^^^^^^^^^^^^^^^^^^
                    hasDescendant(cxxNewExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func")))),
                                    //^^^^^^^^^^^^^^^^^^^
                    hasDescendant(callExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func"))))))
          .bind("var"),
      this);

The language definition doesn't give you any guarantees here, but since virtually every implementation (that is, there are none I know of that don't) implements IEEE-754 math, which does not throw exceptions, it's not something I'd worry about. 语言定义在这里没有给你任何保证,但是因为几乎每一个实现(也就是说,我都不知道)没有实现IEEE-754数学,它不会抛出异常,所以我不是担心。 And more generally, a floating-point math package that throws exceptions would have had to be written with C++ in mind; 更一般地说,抛出异常的浮点数学包必须用C ++编写; that's highly unlikely. 这是不太可能的。

However, you may well get messages when a floating-point error occurs that refer to a "floating-point exception"; 但是,当发生引起“浮点异常”的浮点错误时,您可能会收到消息; that's a floating-point exception, not a C++ exception, and it has nothing to do with C++ exceptions. 这是一个浮点异常,而不是C ++异常,它与C ++异常无关。 It's a runtime error, with a peculiar name. 这是一个运行时错误,具有一个特殊的名称。

Arithmetic cannot throw an exception in C++. 算术不能在C ++中引发异常。 With the usual caveat that if code causes undefined behaviour then anything can happen. 通常需要注意的是,如果代码导致未定义的行为,那么任何事情都可能发生。 So you can mark your function as noexcept . 因此,您可以将您的功能标记为noexcept

Floating point multiplication may cause undefined behaviour if the result would be out of range. 如果结果超出范围,浮点乘法可能会导致未定义的行为。

The "floating point exceptions" are flags that don't interrupt your program: you must test for them using std::fetestexcept and then you can decide what to do. “浮点异常”是不会中断程序的标志:您必须使用std::fetestexcept测试它们,然后您可以决定要做什么。 Several of the FE_ flags listed here may be raised by floating point multiplication. 这里列出的几个FE_标志可以通过浮点乘法引发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM