Bug when using boost::optional with boost::program_options?
Before I spend too long tracking this down (I'm only seeing it in an
Appveyor Windows build, since I do most of my work on Linux), I wanted
to see if anyone else has experienced this issue. I'm trying to use
boost::program_options to parse a command line arg and store it into a
boost::optional, however I get a surprising compilation error[1].
This appears to have been introduced sometime between Boost 1.60 and
1.62 (Appveyor doesn't have Boost 1.61). I see that there were some
significant changes to boost::optional between those revisions, so maybe
that's the cause? The following test case *might* reproduce the issue,
but sadly, rextester only has Boost 1.60, so it works there[2]. If it
fails for someone with Boost 1.62+, then great! (Well, not "great", but
you know what I mean.)
Interestingly, it's not until Boost 1.65[3] that boost::program_options
claims to support storing values into boost::optional; it's worked for
me since long before that, possibly because I `#include
On 2 June 2018 at 07:53, Jim Porter via Boost-users < boost-users@lists.boost.org> wrote:
If it matters, the Appveyor build I'm seeing this with uses Visual Studio 2015 Update 3.
VS2015 has been qualified (quite some time ago already, on reddit) as "buggy" and "to be dropped", because of that, by STL. VS2017 has <optional> and it is ABI-compatible with VS2015. degski -- *"If something cannot go on forever, it will stop" - Herbert Stein*
On 6/1/2018 11:19 PM, degski via Boost-users wrote:
On 2 June 2018 at 07:53, Jim Porter via Boost-users
mailto:boost-users@lists.boost.org> wrote: If it matters, the Appveyor build I'm seeing this with uses Visual Studio 2015 Update 3.
VS2015 has been qualified (quite some time ago already, on reddit) as "buggy" and "to be dropped", because of that, by STL. VS2017 has <optional> and it is ABI-compatible with VS2015.
Good to know. I don't follow Windows dev super closely, so I guess I was trying to provide more support for VS2015 than is warranted. :) - Jim
VS2015 has been qualified (quite some time ago already, on reddit) as "buggy" and "to be dropped", because of that, by STL. VS2017 has <optional> and it is ABI-compatible with VS2015.
Good to know. I don't follow Windows dev super closely, so I guess I was trying to provide more support for VS2015 than is warranted. :)
- Jim
Regardless of what was written above (or what permeates reddit, etc), most shops are still using VS2015 or lower, so it does matter, actually. The fact is that a lot of places are slow to upgrade toolchains because there's a cost to doing so, regardless of what the vendor recommends. There are still places using VC6, for example, so I'd wager that the vast majority of windows devs are not using VS2017. -- chris
On 5 June 2018 at 15:41, Chris Glover via Boost-users < boost-users@lists.boost.org> wrote:
Regardless of what was written above (or what permeates reddit, etc), most shops are still using VS2015 or lower, so it does matter, actually.
If one doesn't care about bugs in compiler, STL and IDE, and support for later standards, why would one care to upgrade Boost at all? I was quoting Steven T. Lavavej https://nuwen.net/stl.html (STL) and Billy O'Neill, who both have leading roles in VC (and its STL) development. The fact you saw it on reddit.com might have something to do with the fact that STL is also one of the moderators of /r/cpp. degski -- *"If something cannot go on forever, it will stop" - Herbert Stein*
Dear Jim, I remember having some troubles using boost::optional with boost::program_options. I fixed it by adding the following lines: namespace boost {// Add custom validator to use boost::program_options on boost::optional<> typestemplate<class T>void validate(boost::any& v, std::vectorstd::string const& values, boost::optional<T>* typeTag, int) { if (!values.empty()) { boost::any a; using namespace boost::program_options; validate(a, values, (T*)0, 0); v = boost::any(boost::optional<T>(boost::any_cast<T>(a))); } } } I don’t remember the details, but I think I took that from more recent version of Boost to be able to use my code with older version of Boost. With that, my code compiles and runs fine - on Linux for Boost from 1.54 to 1.66 with various compilers (GCC 4.8 to 7.3, Intel Compiler, Clang) - on Windows for Boost 1.60 with MSVC++ from 9 (2008) to 14 (2015). I hope this will help. Best regards, Xavier On Tue, Jun 5, 2018 at 5:21 PM degski via Boost-users < boost-users@lists.boost.org> wrote:
On 5 June 2018 at 15:41, Chris Glover via Boost-users < boost-users@lists.boost.org> wrote:
Regardless of what was written above (or what permeates reddit, etc), most shops are still using VS2015 or lower, so it does matter, actually.
If one doesn't care about bugs in compiler, STL and IDE, and support for later standards, why would one care to upgrade Boost at all?
I was quoting Steven T. Lavavej https://nuwen.net/stl.html (STL) and Billy O'Neill, who both have leading roles in VC (and its STL) development. The fact you saw it on reddit.com might have something to do with the fact that STL is also one of the moderators of /r/cpp.
degski -- *"If something cannot go on forever, it will stop" - Herbert Stein* _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Dr Xavier BESSERON Research associate FSTC, University of Luxembourg Campus Belval, Office MNO E04 0415-040 Phone: +352 46 66 44 5418 http://luxdem.uni.lu/
On 6/5/2018 8:51 AM, Xavier Besseron wrote:
Dear Jim,
I remember having some troubles using |boost::optional| with |boost::program_options|. I fixed it by adding the following lines: [snip]
Wow, thanks! I think this is what I needed to get something resolved here. I actually did something *very* similar to the code you wrote (I think there's a sample of something like this buried in the program_options docs somewhere) and totally forgot. Taking a fresh look at the compilation error, I see that it passes through this function in the middle of the template instantiation stack, so this is almost certainly involved in the problem. Now, why my `validate` function only fails when I'm using MSVC (I tested it on VS2017 and it still happens there) with boost::optional (as opposed to std::optional) and Boost 1.62+, I'm still not sure. It's possible there's still a bug here, but I'll have to continue investigating. - Jim
On 6/5/2018 8:51 AM, Xavier Besseron wrote:
I remember having some troubles using |boost::optional| with |boost::program_options|. I fixed it by adding the following lines: [snip] I don’t remember the details, but I think I took that from more recent version of Boost to be able to use my code with older version of Boost. With that, my code compiles and runs fine
* on Linux for Boost from 1.54 to 1.66 with various compilers (GCC 4.8 to 7.3, Intel Compiler, Clang) * on Windows for Boost 1.60 with MSVC++ from 9 (2008) to 14 (2015).
I finally got everything working, and based on your code, you'll have the same issue if you start using Boost 1.62+ on MSVC. I didn't delve too deep into the why, but putting your `validate` function in the `boost` namespace and `using namespace boost::program_options` will introduce an ambiguity when constructing a `boost::optional` (it's trying to find the `detail` namespace and gets confused). I resolved it like this: https://github.com/jimporter/mettle/blob/7ea222a58537bd366ec0cf864de30d29695.... Thanks again for the pointer! - Jim
On 5 June 2018 at 18:51, Xavier Besseron via Boost-users < boost-users@lists.boost.org> wrote:
I hope this will help.
Maybe you should/could create a PR, then in the future (if and when it get's merged, you don't have to fiddle with the boost code either). Have a good day, degski -- *"If something cannot go on forever, it will stop" - Herbert Stein*
On 6/5/2018 8:50 PM, degski via Boost-users wrote:
On 5 June 2018 at 18:51, Xavier Besseron via Boost-users
mailto:boost-users@lists.boost.org> wrote: I hope this will help.
Maybe you should/could create a PR, then in the future (if and when it get's merged, you don't have to fiddle with the boost code either).
Code similar to what Xavier posted is in Boost 1.65+, but if you want to support earlier versions of Boost (or use std::optional instead of boost::optional), you have to do something like that. It would probably be worth adding an overload that works with std::optional, but I don't know if I'll have time in the near future to shepherd a patch into Boost. - Jim
participants (4)
-
Chris Glover
-
degski
-
Jim Porter
-
Xavier Besseron