Opened 6 years ago

Closed 6 years ago

#5494 closed Bugs (wontfix)

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

Reported by: Rupert Kittinger-Sereinig <rks@…> Owned by: Antony Polukhin
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

Attachments (0)

Change History (4)

comment:1 Changed 6 years ago by Antony Polukhin

Owner: changed from nasonov to Antony Polukhin
Status: newassigned

comment:2 Changed 6 years ago by Antony Polukhin

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 6 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 6 years ago by Antony Polukhin

Milestone: To Be DeterminedBoost 1.47.0
Resolution: wontfix
Status: assignedclosed

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Antony Polukhin.
The resolution will be deleted.

Add Comment

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

Note: See TracTickets for help on using tickets.