Opened 14 years ago
Closed 13 years ago
#2295 closed Bugs (fixed)
Inconsistent behavior when using 64 bit integer types
Reported by: | Owned by: | nasonov | |
---|---|---|---|
Milestone: | To Be Determined | Component: | lexical_cast |
Version: | Boost 1.36.0 | Severity: | Problem |
Keywords: | lexical_cast 64 uint64_t int64_t | Cc: |
Description
1) Converting 64bit unsigned int to it's max value string representation and back results in exception (should be identity operation!):
boost::uint64_t max = numeric_limits<boost::uint64_t>::max(); std::string s = lexical_cast<string>(max); BOOST_CHECK_EQUAL(max, lexical_cast<boost::uint64_t>(s)); // crashes: std::bad_cast: bad lexical cast: source type value could not be interpreted as target
2) Precise conditions when the conversion will fail are not specified in the documentation. Throwing of bad_lexical_cast is inconsistent:
#define T short // add a digit to a min representation! s = lexical_cast<string, T>(numeric_limits<T>::min()) + "0"; BOOST_CHECK_THROW(lexical_cast<T>(s), boost::exception); // throws s = lexical_cast<string, T>(numeric_limits<T>::min()) + "5"; BOOST_CHECK_THROW(lexical_cast<T>(s), boost::exception); // throws #define T boost::int64_t s = lexical_cast<string, T>(numeric_limits<T>::min()) + "0"; BOOST_CHECK_THROW(lexical_cast<T>(s), boost::exception); // DOES NOT throw!?!? s = lexical_cast<string, T>(numeric_limits<T>::min()) + "5"; BOOST_CHECK_THROW(lexical_cast<T>(s), boost::exception); // throws
Change History (5)
comment:1 by , 14 years ago
comment:2 by , 14 years ago
Update: the 2. problem seems to be caused by the MSVC streams bug, and the 1. might also probably caused by it.
Nevertheless, lexical_cast tests really should include tests for 64bit integer types.
follow-up: 4 comment:3 by , 14 years ago
Nevertheless, lexical_cast tests really should include tests for 64bit integer types.
They do. Search for LCAST_TEST_LONGLONG in http://svn.boost.org/svn/boost/branches/release/libs/conversion/lexical_cast_test.cpp
Though, I don't understand/remember why it uses int64 rather than boost::long_long_type.
I should also add a test for boost::intmax_t type.
comment:4 by , 14 years ago
Replying to nasonov:
Nevertheless, lexical_cast tests really should include tests for 64bit integer types.
They do. Search for LCAST_TEST_LONGLONG in http://svn.boost.org/svn/boost/branches/release/libs/conversion/lexical_cast_test.cpp
They do indeed. Didn't notice it before when I was looking.
Though, I don't understand/remember why it uses int64 rather than boost::long_long_type.
The link you posted tests boost::long_long_type if BOOST_HAS_LONG_LONG is defined (and seems fall back on int64 defending on few other defined).
I should also add a test for boost::intmax_t type.
May I suggest adding more tests that check conversion failure in the generic testing routines - there is currently not a single one failure test in them (and therefore not a single failure test for long long), there are only tests for around min, max, 0 and exp(10).
Eg. for "test_conversion_from_integral_to_string" something like my second use case would fit nicely: typedef std::basic_string<CharT> string_type; for(i = 0; i <= 10; ++i) {
string_type underflow_str = to_str<CharT>(limits::min()) + to_str<CharT>(i); BOOST_CHECK_THROW(lexical_cast<T>(underflow_str), bad_lexical_cast);
string_type overflow_str = to_str<CharT>(limits::max()) + to_str<CharT>(i); BOOST_CHECK_THROW(lexical_cast<T>(overflow_str), bad_lexical_cast);
} (this check overflow and underflow by appending digits, not by strictly increasing the min/max by +/-1, although that could also be done.)
comment:5 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Note: tested on MS VC9 (without SP1)