tags:

views:

149

answers:

2

I'm using boost::program_options and it suffers from the same as many other c++ libs, even std itself: It still uses C-style null-terminated strings, because nobody really likes the weak std::string.

The method in question is:

options_description_easy_init&
operator()(const char* name,
           const value_semantic* s,
           const char* description);

The typical use case is just fine:

options.add_options()
    ("graphical", bool_switch(&isGraphical)->default_value(false),
     "Show any graphical output during runtime")

However, I need the name of the option to be set dynamically. The reason is that in some cases I nead a custom prefix, which is added to the string by my function std::string key(const std::string& k):

options.add_options()
    (key("graphical"), bool_switch(&isGraphical)->default_value(false),
     "Show any graphical output during runtime")

This fails.

I could now use c_str() on the std::string but that's evil -- I don't know how long program_options keeps the variable around and if my string is still alive when needed.

I could also reserve memory in a buffer etc. and hand in that. The buffer is never freed and it sucks/is evil.

Is there anything else I can do to circumvent the C-style string mess in this situation?

+5  A: 

It's pretty strong convention to not hold on to const char*'s beyond the life of a function call like this. As long as they're not bucking this convention, .c_str() is the expected and best way to do what you're trying to do IMO.

options.add_options()
    (key("graphical").c_str(), bool_switch(&isGraphical)->default_value(false),
     "Show any graphical output during runtime")
Will Robinson
Well, a more elegant solution is not in sight, right? What I mean is that I would prefer key to return the const char* in the first place, but then the string object will definitely die too early..
ypnos
@ypnos: `std::string` wouldn't necessarily fix the lifetime issue - if the interface took a `std::string` pointer or reference you'd still have a problem of wondering if the function made a copy or if you need to keep what you passed in alive. Of course, if the function took a `std::string` value, then you wouldn't have to care. I wonder if there's a reason they don't provide an overload for that?
Michael Burr
Well, if a function takes const std::string)
ypnos
@ypnos: It sounds like you have a good grasp of the issues here. So your question can be rephrased as: "Am I missing anything?" And the answer is no, you're not missing anything. :-) In general if a C++ function takes a pointer or reference, the compiler simply cannot assure you that the callee will not hold on to that pointer or reference after the call returns. You're left with convention, documentation, inspection of the implementation, or as a last resort intentionally leaking some memory. Usually the first two suffice. :) Good luck!
Will Robinson
+1  A: 

I agree with Will that it is unlikely that the parameter will be referenced beyond the function call. However, if you really think that is an issue, you could use a static string or char array to store the output of key() and pass that into the operator()(). Though, this might be the same as a single memory leak depending on your point of view.

SigmaXiPi