Re: Where is RAII when you need it?
Alf P. Steinbach wrote:
For my own little hobby programming I therefore (among many other
semi-good reasons) use a write-it-once-and-be-done-with-it `main`
function that catches any standard exception, as follows:
<snip>
which you can use like this (also this provided in an include file, but
it's questionable whether that can be called a "header"):
[code file="cppx/default_main.impl.hpp"]
// Implementation file.
#include <rfc/cppx/process/invoke_main.hpp>
extern void cpp_main();
auto main() -> int { return cppx::process::invoke_main( &cpp_main ); }
[/code]
whence we get down to the nitty-gritty, namely what you then write in
each using program, like this:
void cpp_main()
{
// blah blah, my "main program" code, may throw
}
#include <rfc/cppx/default_main.impl.hpp>
Of course the include directive can be anywhere, and alternatively it
can be replaced with linking, or even (gasp!) writing the one-liner
`main` -- shown earlier above -- oneself...
That's an awfully complicated way to implement a wrapper for main.
Just about all of my applications use a code generated main that parses
the application's command line options into a struct which it passes to
the application entry point. I think this is both as simple and as
complex as the solution needs to be.
An example (io is the application namespace, utils::ArgV is a typedef
for a vector of strings):
void run( const io::Setup&, utils::ArgV& );
int
main( int argc, char** argv )
{
try
{
io::setup.argv0 = argv[0];
utils::loadOptions();
utils::ArgV args( &argv[1], &argv[argc] );
io::Option::load( args, io::setup, io::requiredOptions );
run( io::setup, args );
return EXIT_SUCCESS;
}
catch( const std::exception& e )
{
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
}
--
Ian Collins