That seems like a juxtaposed statement, for it is C++ exceptions that
instigate the NEED for the RAII idiom. Without exceptions, RAII is merely
a convenience (still nice, but not important/necessary).
That's a matter of opinion.
The first thing that Bjarne Stroustrup added to C to make C++ was
destructors, more or less. In his own words in this forum, it predated
all the other cool things, like templates, virtual, exceptions, by
years. I agree with Bjarne that the thing I miss the most when I'm
forced to do C, or maintain C-like C++ code, is destructors.
The utility of destructors is not mere syntactic sugar like a ranged-
based for loop ala Java and C++0x or even the virtual keyword.
Implicit calling of functions when objects leave scope is incredibly
"powerful" and useful. It greatly reduces a whole class of programming
errors. It does this IMHO in two main ways. First it helps the
programmer not forget to add a free-resource call to a deinit call
(now also usually a destructor), and helps the programmer not forget a
free-resource call (now also usually a destructor) on an exit path in
a function.
Second, it helps foster a certain kind of programming paradigm where
the coder ensures that all resources have an owner at all times. Most
of the time, that is except for the occasional no-throw block or no-
throw operation which transfers ownership or allocates a resource, you
can unwind the stack at any time and you will not leak resources -
required with exceptions, but still useful otherwise. When all
resources have a clearly identified owner (and thus destruction
condition), and the ownership graph in large part has all of its roots
in stack objects, leaks become much rarer, especially with the
idiomatic usage.
I'm not sure what this example is worth, but here it is.
In my little make replacement that I wrote and play around with in my
spare time, I have a grand total of 13 actual "delete"s (and no frees,
etc.). 11149 lines of code, for whatever that silly measurement is
worth.
Once I get C++0x std::function, take off 2. If I had a
std::auto_array, take off 2 more. (Dealing with C interfaces.) Another
2 for dealing with other misc C interfaces. If I had a
std::vector<T*>, std::set<T*>, std::map<---, T*> that owned its
contained pointers, scratch another 4. The last 3 are some hacky
stuffs that I'm doing with "delete this;". (Speaking of that, I should
refactor that to be more sane. Not sure what I was thinking.)
All of the deletes appear in destructors, or they are early deletes
that a later delete in a destructor would catch anyway. I have a /
tolerable/ measure of certainty that my code is leak free, at least
much better than I would have if it was C-style.