Is it a bug in example.cpp?
When I pass -o a, -o=a, --output a or --output=a, the program shows different results!!! It seems only --output=a works. I think it unexpected.
Found in master and v2.2.0. Compiled with g++ -std=c++11, g++ 7.5.0 in Ubuntu 18.04.
This is an unfortunate side-effect of having default and implicit parameters. If you look at the help output you will see this
-o, --output [=BIN(=b.def)] Output file (default: a.out)
In this case --output has a default value of a.out, meaning that it is always present even if not passed on the command line, and an implicit value of b.def, meaning that if you pass -o, --output then the value is b.def. To override it you have to pass --output=foo. The short form -o=a isn't valid syntax, so it is parsed as a positional argument, and both -o a and --output a don't work because of the implicit value, so the parser can't tell if you are writing --output followed by a position argument a.
This was all done a couple of years ago with the input of several people, and the current behaviour was eventually agreed on because the previous behaviour was even more unexpected. However, I really don't like this as it is, since it is so unintuitive and confusing as you have found. I would be inclined to rip it out completely and handle all this differently, but I'm not sure how to do that yet.
Yes, it's confuing. Users don't know how it works and programmers have to get deep into the source codes.
I've just come across a case where --option=1 works as expected, but --option 1 doesn't -- it falls back to the implicit value. -o 1 also falls back to the implicit value while -o=1 fails with an error message.
I'm not sure if I've quite understood your comment, but to me this seems to be the same issue. This is forcing me to look for a different argument parsing library and is exactly the kind of inconsistency I was trying to avoid when I chose to use a 3rd party lib instead of rolling my own.
That's the expected behaviour. I've also checked that this is how boost program options works, so for users of that it is the most compatible behaviour.
What do you expect it to do? I'm thinking of just dropping the implicit idea completely, because I haven't really seen anyone use it in a practical way.
I would expect
--option=1,--option 1,-o=1and-o 1to be equal in all things, i.e. to set the value of the associated variable to1--optionand-oto fall back to the implicit value if one is provided, otherwise they should complain about a missing argument
Implicit values are (or would be, I suppose) very useful to me because my project contains a number of features that can be toggled on or off and should take some parameter when toggled on. So someone can do --feature to just enable it with a reasonable default or --feature 1000 to provide their own parameter.
Thanks for getting back to me on this!
Unfortunately this is the problem with implicit parameters and what I call positional parameters, often filenames. If you write gcc --option-with-implicit-value file.c, then instead of compiling file.c it will attach file.c to --option-with-implicit-value, which is why you have to write --option=file.c.
I would expect
--option=1,--option 1,-o=1and-o 1to be equal in all things, i.e. to set the value of the associated variable to1--optionand-oto fall back to the implicit value if one is provided, otherwise they should complain about a missing argumentImplicit values are (or would be, I suppose) very useful to me because my project contains a number of features that can be toggled on or off and should take some parameter when toggled on. So someone can do
--featureto just enable it with a reasonable default or--feature 1000to provide their own parameter.Thanks for getting back to me on this!
It's also what I expect. The current behavior also confusing to me, and I have to give up the implicit value.