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 1449std::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.