Opened 11 years ago

Closed 5 years ago

#5983 closed Bugs (fixed)

Stack overflow with Karma floating point generator

Reported by: matt.chambers42@… 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)

real_utils.diff (967 bytes ) - added by Daniel Krügler <daniel.kruegler@…> 8 years ago.
SVN patch file

Download all attachments as: .zip

Change History (6)

comment:1 by Hartmut Kaiser, 11 years ago

Status: newassigned

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.

by Daniel Krügler <daniel.kruegler@…>, 8 years ago

Attachment: real_utils.diff added

SVN patch file

comment:2 by Daniel Krügler <daniel.kruegler@…>, 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:3 by xreborner@…, 7 years ago

I also encountered this problem. Four year passed, still not solved?

comment:4 by mike.gresens@…, 5 years ago

comment:5 by Joel de Guzman, 5 years ago

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.