Search code examples
c++boostunique-ptrraiiboost-program-options

RAII with boost boost::program_options and options_description


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.


Solution

  • 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");