docopt / docopt.cpp

C++11 port of docopt
Boost Software License 1.0
1.05k stars 146 forks source link

Consider removing noexcept on `docopt::docopt()`. #46

Closed chrisdembia closed 7 years ago

chrisdembia commented 8 years ago

Right now, docopt::docopt() is marked as noexcept. However, it can throw exceptions. In particular, it threw a std::regex_error(). Because of the noexcept, this caused the program to terminate. It would have been nice for me to have the chance to give a more meaningful error message when docopt gives that exception. What is the reason for the noexcept?

jaredgrubb commented 7 years ago

Sorry for the delay on this. I dont think that this code should throw. Do you have the stack shot or reason why it threw?

chrisdembia commented 7 years ago

The reason for the std::regex_error was error_stack:

There was insufficient memory to determine whether the regular expression could match the specified character sequence.

I think it was because of a somewhat confusing doc string. I was able to simplify my doc string and avoid the error. It only occurred on Windows (so, using the Microsoft's standard library); not with gcc/clang.

How can you know that the function won't throw if you call functions that are not themselves marked noexcept?

jaredgrubb commented 7 years ago

There are known issues with Microsoft's regex implementation (#49) that are a bug on Microsoft's side. We're looking at how we can workaround these so that docopt is usable on that platform.

We can ensure that docopt::docopt will not throw by code inspection. If there's a case where we miss something, then we need to add a try-catch to handle it. I'm not aware of anything we have missed. Our contract with "docopt::docopt" is that the function either succeeds (success) or exits and prints the usage string (invalid user input). For the case of regex_error, this should only throw if the regex strings are invalid, but these are completely under our control so this is not expected to ever happen.

Note that there is docopt::docopt_parse which does not swallow exceptions and would allow your code to handle whatever it likes. The intent of this one was the case where you might want a fallback in case one usage string fails (eg, legacy handling), but I suppose you could implement something more defensive if you like.

I think having a noexcept interface is a feature and I dont think we should remove it.

chrisdembia commented 7 years ago

Okay thank you for explaining.

jaredgrubb commented 7 years ago

Thanks for the questions .. always appreciate hearing feedback!

chrisdembia commented 7 years ago

Thank you for the great library :)

If you want, you can see how I use it here: https://github.com/opensim-org/opensim-core/tree/master/Applications/opensim-cmd

jaredgrubb commented 7 years ago

That's cool! I wonder if it would be helpful to add a "GitHub projects using docopt" link to make it easy for people to find examples.