I could be totally off in my understanding of the use of RAII class to ensure resources are released, but the following example appears to show that a local object of a RAII class need not be able to release its resource when the program crashes:
// Compiled via command:
// /c/opt/mingw64/bin/x86_64-w64-mingw32-g++.exe -D_WIN64 -Wall -Wextra -Werror -std=c++11 -O3 -static-libgcc -static-libstdc++ local_raii.cc -o local_raii.exe
#include <fstream>
#include <iostream>
#include <thread>
#include <mutex>
class some_raii
{
public:
some_raii( int i, const char *message ) : which_one(i)
{
std::unique_lock<std::mutex> mu_lock( mu );
of() << "Started "
<< which_one
<< " "
<< message
<< "\n";
of().flush();
}
~some_raii()
{
std::unique_lock<std::mutex> mu_lock( mu );
of() << "Done with "
<< which_one
<< "\n";
of().flush();
}
static std::ofstream& of();
static std::mutex mu;
int which_one{0};
};
std::ofstream& some_raii::of()
{
static std::ofstream a_of( "output.txt" );
return a_of;
}
std::mutex some_raii::mu;
some_raii globals_destructor_is_called( 100, "" );
int main()
{
some_raii locals_destructor_is_NOT_called( 201, "destructor will not be called -- where's the resource release via RAII?" );
{
some_raii fhoo( 301, "" );
}
std::chrono::milliseconds interval( 500 );
std::cout << "press CTRL-C to terminate this program ...\n"
<< std::flush;
while(1)
{
static int i = 400;
some_raii fgoo( i++, "where's the resource release via RAII for the _last_ one?" );
std::this_thread::sleep_for( interval );
};
std::cout << "This line will not be seen\n" << std::flush;
return 0;
}
As can be seen from the output from one run of above program:
Started 100
Started 201 destructor will not be called -- where's the resource release via RAII?
Started 301
Done with 301
Started 400 where's the resource release via RAII for the _last_ one?
Done with 400
Started 401 where's the resource release via RAII for the _last_ one?
Done with 401
Started 402 where's the resource release via RAII for the _last_ one?
Done with 100
the destructors of a local RAII object need not be called when the program crashes. So if this RAII object opened some hardware in its constructor then that hardware would not be closed (since its destructor is never executed).
Questions: Does the C++11 standard provide some mechanism to allow use of local RAII objects to manage a resource such as opening and closing some hardware? If it doesn't then, since Bjarne Stroustrup promotes the use the RAII class, why is he OK with the behavior illustrated here?