Re: Where is RAII when you need it?
 
On 17.11.2013 20:19, Stefan Ram wrote:
   Today, I wanted to show RAII, like this:
#include <iostream>
#include <ostream>
#include <stdexcept>
struct K
{ K (){ ::std::cerr << "K"  << ::std::endl; }
   ~K(){ ::std::cerr << "~K" << ::std::endl; }};
struct R
{ K * k; R() : k{ new K{} }{}
   ~R() { ::std::cerr << "~R" << ::std::endl; delete k; }};
int main(){ R r{}; throw ::std::runtime_error( "error" ); }
   The output was:
K
terminate called after throwing an instance of 'std::runtime_error'
   what():  error
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
--------------------------------
Process exited with return value 3
This is the usual process exit code from `abort`.
   No ~K nor ~R in sight! Why?
It's unspecified whether stack unwinding happens when there is no 
handler for an exception.
In this case, with this compiler, it didn't happen.
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:
[code file="cppx/process/invoke_main.hpp"]
#pragma once
// Copyright (c) 2013 Alf P. Steinbach.
#include <rfc/cppx/Type_.h>                 // cppx::Type_, cppx::Type
#include <rfc/cppx/process/Exit_code.h>     // 
cppx::process::Exit_code::Enum
#include <functional>       // std::function
#include <iostream>         // std::clog
#include <stdexcept>        // std::exception
#include <system_error>     // std::system_error
namespace cppx{ namespace process{
     using std::exception;
     using std::function;
     typedef Type_T_<void()>::T          Main_function;
     typedef function<Main_function>     Main_functor;
     typedef cppx::Type_T_<bool( exception const& )>::T  Logger_function;
     typedef function<Logger_function>                   Logger_functor;
     inline bool stderr_logger( exception const& x )
     {
         using namespace std;
         cerr << "!" << x.what();
         if( auto p_syserr = dynamic_cast<system_error const*>( &x ) )
         {
             cerr << " (error code 0x" << uppercase << hex << 
p_syserr->code().value() << ")";
         }
         cerr << endl;
         return !!clog;
     }
     inline int invoke_main(
         Main_functor const&     cpp_main,
         Logger_functor const&   log         = stderr_logger
         )
     {
         try
         {
             cpp_main();
             return Exit_code::success;
         }
         catch( exception const& x )
         {
             log( x );
             return Exit_code::failure;
         }
         catch( ... )
         {
             throw;      // Uh oh.
         }
     }
} }  // namespace cppx::process
[/code]
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...
Cheers & hth.,
- Alf
PS: There has been an article series about using a standard 
write-it-once-and-be-done-with-it `main` in the ACCU Overload Journal. I 
haven't read it though. Skimming lightly through one of the articles I 
think I saw some not very general interest code there, but it may still 
be worth checking out.