Following an example on net From this answer I came up with this:
int server_port;
auto value_port = new po::typed_value<int>(&server_port); //<-- Really??
value_port->value_name("port");
po::options_description opt_config("Configuation");
opt_config.add_options()("port,P", value_port, "listening port");
This apparently works. However explicitly calling new
to create raw pointers in C++ raised alarm bells.
So the first thing I tried was to use a statically allocated object. (I don’t see the need for dynamically allocated memory here):
auto value_port = po::typed_value<int>(&server_port);
value_port.value_name("port");
po::options_description opt_config("Configuation");
opt_config.add_options()("port,P", &value_port, "listening port");
This gives a run time error at function exit (when variables are being destructed).
The call stack starts with
boost::detail::shared_count::~shared_count() Line 447
and the error is at
boost::checked_delete<boost::program_options::value_semantic const >(const boost::program_options::value_semantic * x) Line 34
where there is a delete
instruction.
The second thing I tried was to use unique_ptr
(from std
):
auto value_port = make_unique<po::typed_value<int>>(&server_port);
value_port->value_name("port");
po::options_description opt_config("Configuation");
opt_config.add_options()("port,P", value_port.get(), "listening port");
The story is similar, with 2 frames this time on the call stack:
std::unique_ptr<boost::program_options::typed_value<int,char>,std::default_delete<boost::program_options::typed_value<int,char> > >::~unique_ptr<boost::program_options::typed_value<int,char>,std::default_delete<boost::program_options::typed_value<int,char> > >() Line 1449
std::default_delete<boost::program_options::typed_value<int,char> >::operator()(boost::program_options::typed_value<int,char> * _Ptr) Line 1200
again at a delete
instruction.
So it seems like options_description
destructs (the object at) the pointer received via add_options
and the problem is caused by 2 destructions on the same object.
Shouldn’t this be documented? Doesn’ț this goes against RAII? The caller creates the object, but it is destroyed by another object that at some point receives a pointer to it. `
I used boost_1_56_0
with Visual Sudio 2013
running a debug x64
configuration.
The way you use it is indeed not exactly RAII. unique_ptr is a nice try. What you have to do is to call release()
instead of get()
:
opt_config.add_options()("port,P", value_port.release(), "listening port");