-
>> Is it good style to catch exceptions "far away" from the place there they get thrown?
Yes, sort of. A common error made when using exceptions is to catch the exception too close to where it is thrown.
The best place to catch an exception is wherever the best place to handle it is. In your case, invalid command line arguments should be handled in main (or the equivalent) so that the application can error out and exit.
It would seem a little weird to catch boost::bad_lexical_cast somewhere far from where you do the cast, though.
If you have multiple command line arguments to process, perhaps you can have a block of code that parses all of them and put that into it's own try/catch, but otherwise I think just leaving it where you have it (or around a main2() type function) is best.
-
You can even do something as silly as
Code:
int main()
try {
//...
}
catch (boost::bad_lexical_cast&)
{
cout << "exception was thrown"
}
But that may indeed not be a good idea if you are not throwing the exceptions yourself, as you'd lose the ability to tell exactly what went wrong (multiple lexical_casts throwing).
-
Why not this?
Code:
int main( int argc, char* argv[] )
{
try
{
// Put all of the main() code in here.
}
catch ( whatever& e )
{
...
}
catch ( blahblah& e )
{
...
}
catch ( ... )
{
cout << "Unexpected exception caught!" << endl;
return 1;
}
return 0;
}
-
Since the ultimate goal here is the parsing of command line options, why not wrap all the option variables in a single class, make them const, and have main() call a function (passing argc and argv) which validates the arguments, builds the options object and returns it? If the options do not validate properly, throw an exception.
Code:
class program_options
{
public:
program_options(int unit_val, int other_val, int foo_val, ...)
: UNIT(unit_val),
OTHER(other_val),
FOO(foo_val)
...
{
}
// Since the options are const, make them public, accessible directly
const int UNIT;
const int OTHER;
const int FOO;
...
};
program_options get_program_options(int argc, char **argv)
{
if(options_not_valid())
{
throw program_option_exception();
}
...
return program_options(unit_val, other_val, foo_val, ...)
}
int main(int argc, char **argv)
{
try
{
program_options opts = get_program_options(argc, argv);
run_program(opts);
return 0;
}
catch(program_option_exception e)
{
show_usage_message();
exit(1);
}
return 0;
}
-
Thats a good solution and I'll probably try it, if I've a more complex option system to handle. for needs of heavy options parsing there's also boost::program_options. but I don't know if it is able to hold const values, too
-
Well, it parses and then gives you values. You can store them in consts.