Subject: Re: [Boost-bugs] [Boost C++ Libraries] #12535: boost::program_options cannot handle std::uint8_t arguments
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-07-08 11:59:41
#12535: boost::program_options cannot handle std::uint8_t arguments
-------------------------------+-----------------------------
Reporter: gilgamash | Owner: Vladimir Prus
Type: Bugs | Status: new
Milestone: To Be Determined | Component: program_options
Version: Boost 1.61.0 | Severity: Problem
Resolution: | Keywords: uint8_t
-------------------------------+-----------------------------
Comment (by Kalle Olavi Niemitalo <kon@â¦>):
== Compile with:
c++ -std=c++11 -Wall -Wextra -Wold-style-cast -pedantic -ggdb
program_options_uint8_demo.cc -lboost_program_options -o
program_options_uint8_demo
== Run with:
./program_options_uint8_demo
== Actual result:
{{{
terminate called after throwing an instance of
'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::invalid_option_value>
>'
what(): the argument ('241') for option '--num' is invalid
}}}
== Backtrace when the exception is being thrown:
0. in !__cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
1. in boost::throw_exception<boost::bad_lexical_cast> (e=...) at
/usr/include/boost/throw_exception.hpp:70
2. in boost::detail::lexical_cast_do_cast<unsigned char,
std::string>::lexical_cast_impl (arg="241") at
/usr/include/boost/lexical_cast.hpp:2375
3. in boost::lexical_cast<unsigned char, std::string> (arg="241") at
/usr/include/boost/lexical_cast.hpp:2543
4. in boost::program_options::validate<unsigned char, char> (v=...,
xs=std::vector of length 1, capacity 1 = {...}) at
/usr/include/boost/program_options/detail/value_semantic.hpp:89
5. in boost::program_options::typed_value<unsigned char, char>::xparse
(this=0x619070, value_store=..., new_tokens=std::vector of length 1,
capacity 1 = {...}) at
/usr/include/boost/program_options/detail/value_semantic.hpp:170
6. in
boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&,
std::vector<std::string, std::allocator<std::string> > const&, bool) const
() from /usr/lib/x86_64-linux-gnu/libboost_program_options.so.1.55.0
7. in
boost::program_options::store(boost::program_options::basic_parsed_options<char>
const&, boost::program_options::variables_map&, bool) () from
/usr/lib/x86_64-linux-gnu/libboost_program_options.so.1.55.0
8. in main () at program_options_uint8_demo.cc:16
== Cause:
lexical_cast sees uint8_t as unsigned char and expects a one-character
string, but "241" has three characters. Likewise, --num=9 would set
num='9', i.e. num=57 in ASCII, not num=9.
== Rationale:
I expect value<char> to parse a one-character argument; if that were
changed to parse an integer, it would be too surprising.
OTOH, options that require a one-character argument and save that as char
don't seem very useful nowadays, because of multibyte characters.
If value<char> parses a one-character argument, and int8_t is defined as
char (rather than signed char), then value<int8_t> is undistinguishable
from value<char> and must likewise parse a one-character argument.
If value<char> parsed a one-character argument but value<unsigned char>
were changed to parse an integer, that would be an annoying asymmetry.
Passing arbitrary raw bytes as unsigned char in the command line is not
feasible because argv[] does not support null bytes and Windows always
requires a conversion from UTF-16.
== Recommendation for programs:
Define the argument type as a string if you want a single character, and
as int if you want an 8-bit integer. Then separately check that the
string isn't too long or that the integer isn't out of range.
== Recommendation for Boost:
Keep value<char> and value<unsigned char> parsing a single-character
argument like now, but change the error message to say that the argument
is too long and a single character was expected. This will make it easier
for the programmer to understand how to fix the problem if integer parsing
was intended.
Perhaps add separate integer_value functions that support uint8_t and
allow the programmer to specify the permitted range of integers.
-- Ticket URL: <https://svn.boost.org/trac10/boost/ticket/12535#comment:2> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-07-08 12:04:04 UTC