Subject: [Boost-bugs] [Boost C++ Libraries] #11826: float128.hpp: too aggressive NOTHROW on converting assignment operator
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-11-30 19:48:53
#11826: float128.hpp: too aggressive NOTHROW on converting assignment operator
-------------------------------------+----------------------------
Reporter: martin.seemann@⦠| Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: multiprecision
Version: Boost Development Trunk | Severity: Regression
Keywords: float128 nothrow |
-------------------------------------+----------------------------
In order to fix another issue, commit
https://github.com/boostorg/multiprecision/commit/9927d49cb9d87c022c3ac49b3c8d84ce55ab7dc4
introduced several unconditional BOOST_NOTHROWs in float128.hpp.
In my opinion, at least some of them are problematic, especially for the
assignment operator (line 150) and the conversion constructor (line 147).
Both support initialization from any type implicitly convertible to the
underlying float128_type. However, implicit conversion routines might
throw, as demonstrated by the following example program:
{{{
// g++ -std=c++11 exception_float128.cpp -o exception_float128 -fext-
numeric-literals -lquadmath
#include <iostream>
#include <stdexcept>
#include <boost/multiprecision/float128.hpp>
struct outer {
template <typename T> struct inner {
T operator()() const {
throw std::runtime_error("Bad stuff happened");
return T{0};
}
};
template <typename Target, typename = typename
std::enable_if<!std::is_same<Target, const char *>::value>::type> operator
Target() const {
return inner<Target>()();
}
};
int main() {
boost::multiprecision::float128 destination;
outer source;
try {
destination = source;
} catch (const std::exception &e) {
std::cerr << "caught exception: " << e.what() << "\n";
}
return 0;
}
}}}
Compiled with recent boost, this code std::terminate's. If BOOST_NOTHROW
in float128.hpp:150 is replaced by
BOOST_NOEXCEPT_IF(noexcept(std::declval<float128_type&>() =
std::declval<const T&>())), the
exception is caught as expected.
Such conditional noexcept specifiers might be required in some more
places, provided there isn't a policy that I am unaware of, which forbids
implicit conversion operators to throw.
(BTW: the above code is not just a twisted mockup. I hit the problem while
developing a conversion library that uses the "template <typename T>
operator T()" trick to let the compiler deduce the target type
automatically. An appropriate functor is then selected that implements the
actual conversion or throws, if no suitable source data is provided.)
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11826> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:19 UTC