浮点乘法可以在 C++ 中抛出异常吗?
can floating point multiplication throw an exception in C++?
这可能吗?我不认为是,但我不知道这是标准会说的,还是实现定义的?我问是因为我想知道像这样标记一个 constexpr 函数是否安全或值得 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
语言定义在这里不给你任何保证,但由于几乎每个实现(也就是说,none我知道没有)实现 IEEE-754 数学,它不抛出异常,这不是我担心的事情。更一般地说,一个抛出异常的浮点数学包必须用 C++ 来编写;那是极不可能的。
但是,当出现引用 "floating-point exception" 的浮点错误时,您可能会收到消息;这是一个 浮点数 异常,而不是 C++ 异常,它与 C++ 异常无关。这是一个运行时错误,具有特殊的名称。
不,浮点数乘法通常不会抛出 C++ 异常。
但是想一想:clang-tidy怎么可能知道to_meter
会不会抛出异常呢?在 C++ 中,每个函数都可以抛出异常,除非明确声明不抛出。
所以 clang-tidy 有两个选择:它可以做昂贵的(可能是不确定的)控制流分析,或者它可以简单地依靠你正确地声明 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);
算术不能在 C++ 中抛出异常。通常的警告是,如果代码导致未定义的行为,那么任何事情都可能发生。所以你可以将你的函数标记为 noexcept
.
如果结果超出范围,浮点乘法可能会导致未定义的行为。
"floating point exceptions" 是不会中断您的程序的标志:您必须使用 std::fetestexcept
测试它们,然后您可以决定要做什么。 FE_ flags listed here中的几个可以通过浮点乘法得到。
这可能吗?我不认为是,但我不知道这是标准会说的,还是实现定义的?我问是因为我想知道像这样标记一个 constexpr 函数是否安全或值得 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
语言定义在这里不给你任何保证,但由于几乎每个实现(也就是说,none我知道没有)实现 IEEE-754 数学,它不抛出异常,这不是我担心的事情。更一般地说,一个抛出异常的浮点数学包必须用 C++ 来编写;那是极不可能的。
但是,当出现引用 "floating-point exception" 的浮点错误时,您可能会收到消息;这是一个 浮点数 异常,而不是 C++ 异常,它与 C++ 异常无关。这是一个运行时错误,具有特殊的名称。
不,浮点数乘法通常不会抛出 C++ 异常。
但是想一想:clang-tidy怎么可能知道to_meter
会不会抛出异常呢?在 C++ 中,每个函数都可以抛出异常,除非明确声明不抛出。
所以 clang-tidy 有两个选择:它可以做昂贵的(可能是不确定的)控制流分析,或者它可以简单地依靠你正确地声明 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);
算术不能在 C++ 中抛出异常。通常的警告是,如果代码导致未定义的行为,那么任何事情都可能发生。所以你可以将你的函数标记为 noexcept
.
如果结果超出范围,浮点乘法可能会导致未定义的行为。
"floating point exceptions" 是不会中断您的程序的标志:您必须使用 std::fetestexcept
测试它们,然后您可以决定要做什么。 FE_ flags listed here中的几个可以通过浮点乘法得到。