Boost C++ Libraries: Ticket #5494: lexical_cast<unsigned int>("-1") fails to throw https://svn.boost.org/trac10/ticket/5494 <p> The following fails to throw: std::cout &lt;&lt; boost::lexical_cast&lt;unsigned int&gt;(std::string("-1")) </p> <blockquote> <p> &lt;&lt; std::endl; </p> </blockquote> <p> output: 4294967295 </p> <p> which looks a lot like static_cast&lt;unsigned int&gt;(-1) </p> <p> boost version: 1.45 compiler: g++ (Debian 4.4.5-8) 4.4.5 </p> <p> For my project, this is a serious problem since lexical_cast is used for input validation </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5494 Trac 1.4.3 Antony Polukhin Fri, 13 May 2011 06:50:06 GMT owner, status changed https://svn.boost.org/trac10/ticket/5494#comment:1 https://svn.boost.org/trac10/ticket/5494#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">nasonov</span> to <span class="trac-author">Antony Polukhin</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Antony Polukhin Fri, 13 May 2011 07:47:58 GMT <link>https://svn.boost.org/trac10/ticket/5494#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5494#comment:2</guid> <description> <p> 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.<br /> I recommend you to use some wrappers, around lexical_cast, like: </p> <pre class="wiki">#include &lt;boost/lexical_cast.hpp&gt; #include &lt;boost/type_traits/is_unsigned.hpp&gt; template &lt;bool is_unsigned&gt; struct unsigned_checker { template&lt;typename String_type&gt; static inline void do_check(const String_type &amp; str) { } }; template &lt;&gt; struct unsigned_checker&lt;true&gt; { template&lt;typename String_type&gt; static inline void do_check(const String_type &amp; str) { if( str[0] == '-' ) boost::throw_exception( boost::bad_lexical_cast() ); } }; template&lt;typename Target, typename Source&gt; inline Target forced_lexical_cast(const Source &amp;arg) { unsigned_checker&lt; boost::is_unsigned&lt;Target&gt;::value &gt;::do_check(arg); return boost::lexical_cast&lt;Target&gt;( arg ); } </pre><p> <br /> Thank you for that bug report! I`ll add your question to the FAQ section of lexical_cast documentation. </p> </description> <category>Ticket</category> </item> <item> <author>Rupert Kittinger-Sereinig <rks@…></author> <pubDate>Fri, 13 May 2011 12:23:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5494#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5494#comment:3</guid> <description> <p> thanks for the explanation, I already implemented a similar workaround. </p> <p> You might als add to the FAQ that this may not be very portable. </p> <p> e.g. with g++-4.3.2, the behaviour was different. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Fri, 13 May 2011 17:52:27 GMT</pubDate> <title>status, milestone changed; resolution set https://svn.boost.org/trac10/ticket/5494#comment:4 https://svn.boost.org/trac10/ticket/5494#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.47.0</span> </li> </ul> Ticket