Sorry for digging up such an old thread, but there is a major error in the following reasoning:
RAII moves the responsibility of exception safety from the user of the object to the designer (and implementer) of the object. I would argue this is the correct place as you then only need to get exception safety correct once (in the design/implementation). By using finally you need to get exception safety correct every time you use an object.
More often than not, you have to deal with dynamically allocated objects, dynamic numbers of objects etc. Within the try-block, some code might create many objects (how many is determined at runtime) and store pointers to them in a list. Now, this is not an exotic scenario, but very common. In this case, you'd want to write stuff like
void DoStuff(vector<string> input){ list<Foo*> myList; try { for (int i = 0; i < input.size(); ++i) { Foo* tmp = new Foo(input[i]); if (!tmp) throw; myList.push_back(tmp); } DoSomeStuff(myList); } finally { while (!myList.empty()) { delete myList.back(); myList.pop_back(); } }}
Of course the list itself will be destroyed when going out of scope, but that wouldn't clean up the temporary objects you have created.
Instead, you have to go the ugly route:
void DoStuff(vector<string> input){ list<Foo*> myList; try { for (int i = 0; i < input.size(); ++i) { Foo* tmp = new Foo(input[i]); if (!tmp) throw; myList.push_back(tmp); } DoSomeStuff(myList); } catch(...) { } while (!myList.empty()) { delete myList.back(); myList.pop_back(); }}
Also: why is it that even managed lanuages provide a finally-block despite resources being deallocated automatically by the garbage collector anyway?
Hint: there's more you can do with "finally" than just memory deallocation.