Ticket #5494 (closed Bugs: wontfix)

Opened 5 years ago

Last modified 5 years ago

lexical_cast<unsigned int>("-1") fails to throw

Reported by: Rupert Kittinger-Sereinig <rks@…> Owned by: apolukhin
Milestone: Boost 1.47.0 Component: lexical_cast
Version: Boost 1.45.0 Severity: Problem
Keywords: lexical_cast Cc:


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

comment:1 Changed 5 years ago by apolukhin

  • Owner changed from nasonov to apolukhin
  • Status changed from new to assigned

comment:2 Changed 5 years ago by apolukhin

boost::lexical_cast has the behavior of stringstream, which uses num_get functions of std::locale to convert numbers. If we look at the [] of Programming languages — C++ ( or at [] 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.

comment:3 Changed 5 years ago by Rupert Kittinger-Sereinig <rks@…>

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 Changed 5 years ago by apolukhin

  • Status changed from assigned to closed
  • Resolution set to wontfix
  • Milestone changed from To Be Determined to Boost 1.47.0

Add a comment

Modify Ticket

Change Properties
<Author field>
as closed
The resolution will be deleted. Next status will be 'reopened'

E-mail address and user name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.