vietjtnguyen / argagg

A simple C++11 command line argument parser
MIT License
224 stars 28 forks source link

argagg::parser_results::operator[] throws std::out_of_range when key does not exsits #18

Closed DWVoid closed 6 years ago

DWVoid commented 6 years ago

stack trace:

__GI_raise 0x00007ffffe145428
__GI_abort 0x00007ffffe14702a
__gnu_cxx::__verbose_terminate_handler() 0x00007ffffe7920d5
<unknown> 0x00007ffffe78fcc6
std::terminate() 0x00007ffffe78fd11
__cxa_throw 0x00007ffffe78ff54
std::__throw_out_of_range(char const*) 0x00007ffffe7b99af
std::__detail::_Map_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, argagg::option_results>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, argagg::option_results> >, std::__detail::_Select1st, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::at hashtable_policy.h:774
std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, argagg::option_results, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, argagg::option_results> > >::at unordered_map.h:981
argagg::parser_results::operator[] argagg.hpp:763
main Application.cpp:55
__libc_start_main 0x00007ffffe130830
_start 0x000000000042b049

Code:

    try { pargs = parser.parse(argc, argv); }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return -1;
    }
    if ( pargs["help"]) {
        argagg::fmt_ostream fmt(std::cerr);
        fmt << "Usage:" << std::endl << parser;
        return 0;
    }

According to the follwing page, the method at() does throw this exception when the key is not found.

http://en.cppreference.com/w/cpp/container/unordered_map/at

I believe that there is a misuse in the argagg code

vietjtnguyen commented 6 years ago

I'm guessing an option named help is not defined in the parser? If so, what would your expectation be for trying to access an option that hasn't been defined? Would you rather simply return an empty parser results object that evaluates to false on boolean conversion?

vietjtnguyen commented 6 years ago

I've updated it so that it now handles std::unordered_map::at()'s std::out_of_range exception and throws an argagg::unknown_option exception with a better error message instead.

vietjtnguyen commented 6 years ago

49ac33422a6b6838c2e6dd1fccd7dcd39f5ea089