简体   繁体   中英

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

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.

But think about this: How can clang-tidy possibly know whether to_meter will throw an exception? In C++ every function can throw an exception unless it is explicitly declared not to throw.

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 :

  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. And more generally, a floating-point math package that throws exceptions would have had to be written with C++ in mind; 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. It's a runtime error, with a peculiar name.

Arithmetic cannot throw an exception in C++. With the usual caveat that if code causes undefined behaviour then anything can happen. So you can mark your function as 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. Several of the FE_ flags listed here may be raised by floating point multiplication.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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