Opened 11 years ago
Closed 5 years ago
#5983 closed Bugs (fixed)
Stack overflow with Karma floating point generator
Reported by: | Owned by: | Hartmut Kaiser | |
---|---|---|---|
Milestone: | To Be Determined | Component: | spirit |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | karma stack overflow | Cc: | Joel de Guzman |
Description
This spirit code causes a stack overflow on MSVC 9 and seg fault on GCC 4.2.1 with boost 1.43 and trunk.
#include <boost/spirit/include/karma.hpp> #include <string> using namespace std; template <typename T> struct double12_policy : boost::spirit::karma::real_policies<T> { // we want to generate up to 12 fractional digits static unsigned int precision(T) { return 12; } }; string to_string(double value) { using namespace boost::spirit::karma; typedef real_generator<double, double12_policy<double> > double12_type; static const double12_type double12 = double12_type(); char buffer[256]; char* p = buffer; generate(p, double12, value); return string(&buffer[0], p); } int main() { cout << to_string(7.0714098800910119e-313); return 0; }
Attachments (1)
Change History (6)
comment:1 by , 11 years ago
Status: | new → assigned |
---|
comment:2 by , 8 years ago
I stumbled across the same issue yesterday using boost 1.55, that is the missing support for denormalized numbers by karma::generate. This is a very nasty bug for us and it basically forbids is to use karma::generate for floating point numbers in our source code, which is really unfortunate due to the otherwise excellent properties of this function and the library.
Since I'm seeing no progress on this bug since three years I would like to help solving it.
First, here is a more specific test-case:
#include <limits> #include <stdexcept> #include <iostream> #include <string> #include "boost/spirit/include/karma.hpp" template <class T> std::string to_string(const T& value) { std::string res; if (!boost::spirit::karma::generate(std::back_inserter(res), value)) throw std::invalid_argument("Could not convert argument to string"); return res; } int main() { try { std::string s = to_string(std::numeric_limits<double>::denorm_min()); std::cout << s << std::endl; } catch (...) { std::cout << "Error!" << std::endl; } }
which crashes due to an assertion failure in "boost/spirit/home/support/detail/pow10.hpp", line 87. The error is understandable, because boost::spirit::traits::pow10 can only handle positive dimensions and it is impossible to map the (negative) exponent of a denormalized number to an exponential value in the domain of the corresponding type by a single multiplication.
Second, I have created an patch file against the recent boost SVN head. Please consider to apply the attached file real_utils.diff.
If you have any further questions or requirements for a patch, please let me know.
comment:5 by , 5 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
7.0714098800910119e-313
is a denormalized floating point number and Karma currently does not support printing those. Nevertheless, the fact that you're seeing a stack overflow is definitely a bug which I will try to fix asap.Independently, because of it being denormalized (the smallest normalized value is
2.2250738585072014e-308
) it does not make any sense to request 12 digits precision anyways, as only 15-5 == 10 digits precision are left for this number.