Opened 12 years ago
Closed 11 years ago
#5494 closed Bugs (wontfix)
lexical_cast<unsigned int>("-1") fails to throw
| Reported by: | Owned by: | Antony Polukhin | |
|---|---|---|---|
| Milestone: | Boost 1.47.0 | Component: | lexical_cast |
| Version: | Boost 1.45.0 | Severity: | Problem |
| Keywords: | lexical_cast | Cc: |
Description
The following fails to throw: std::cout << boost::lexical_cast<unsigned int>(std::string("-1"))
<< std::endl;
output: 4294967295
which looks a lot like static_cast<unsigned int>(-1)
boost version: 1.45 compiler: g++ (Debian 4.4.5-8) 4.4.5
For my project, this is a serious problem since lexical_cast is used for input validation
Change History (4)
comment:1 by , 11 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:2 by , 11 years ago
comment:3 by , 11 years ago
thanks for the explanation, I already implemented a similar workaround.
You might als add to the FAQ that this may not be very portable.
e.g. with g++-4.3.2, the behaviour was different.
comment:4 by , 11 years ago
| Milestone: | To Be Determined → Boost 1.47.0 |
|---|---|
| Resolution: | → wontfix |
| Status: | assigned → closed |
Note:
See TracTickets
for help on using tickets.

boost::lexical_cast has the behavior of stringstream, which uses num_get functions of std::locale to convert numbers. If we look at the [22.2.2.1.2] of Programming languages — C++ ( or at [22.2.2.1.2] Working Draft, Standard for Programming Language C++) we`ll see, that num_get uses the rules of scanf for conversions. And in the C99 standard for %u the input value minus sign is optional, so if a negative number is read, no errors will arise and the result will be the two's complement.
I recommend you to use some wrappers, around lexical_cast, like:
#include <boost/lexical_cast.hpp> #include <boost/type_traits/is_unsigned.hpp> template <bool is_unsigned> struct unsigned_checker { template<typename String_type> static inline void do_check(const String_type & str) { } }; template <> struct unsigned_checker<true> { template<typename String_type> static inline void do_check(const String_type & str) { if( str[0] == '-' ) boost::throw_exception( boost::bad_lexical_cast() ); } }; template<typename Target, typename Source> inline Target forced_lexical_cast(const Source &arg) { unsigned_checker< boost::is_unsigned<Target>::value >::do_check(arg); return boost::lexical_cast<Target>( arg ); }Thank you for that bug report! I`ll add your question to the FAQ section of lexical_cast documentation.