George said:
A related question if I may: Is garbage collection necessary if the
programmer follows a strict RAII design ie. only allocating and
deallocating resources in constructors and destructors? Is garbage
collection just to enable you to program more like Java ie. creating
objects on the heap by using new everywhere? What is the advantage of this?
In my previous job I worked for over 5 years in an extensive C++
project, and in my current job I have done so for over 1.5 years.
Although counting lines of code is not really a perfect measurement of
the amount of work done, and I haven't measured exactly how much code I
have written in total in these two jobs, I wouldn't be surprised if it
was well over 100k LOC. Many of the programs deal with dynamically
allocated memory in rather complex ways.
I have from time to time checked for memory leaks in all my programs
with profilers. How many memory leaks have I had in all these years in
all my C++ programs? Zero. Not even once have I had a single memory leak
in any of my code. During these tests I have found many memory leaks in
third-party libraries (which I had to then fix myself), but none in my
own code.
Also I don't remember even once having accessed freed memory. I have
had a few cases where I have accessed allocated memory out of boundaries
(usually because of an off-by-1 mistake), but even those have been less
than a dozen (mostly in the earlier years), and caught rather quickly.
I really haven't ever felt the need for a GC engine in my work. Could
a GC engine have made my job easier in a few cases? Maybe. I can't say
for sure. At most it could have perhaps saved a bit of writing work, but
not increased the correctness of my code in any way. C++ makes it quite
easy to write safe code when you follow some simple rules.
Java also has the finally block, and I understand this won't be
implemented in C++(0x) any time soon because it's not necessary with
RAII.
I must admit I don't have too much Java programming experience, but if
I'm not completely mistaken, finally-blocks can be used in Java, for
example, to do things like this (in pseudo-java):
void foo()
{
try
{
infile = open_file_here;
perform_lots_of_complicated_stuff_which_might_throw;
}
finally
{
close(infile);
}
}
Of course in situations like this there just is no need for a
'finally' block in C++, as the same effect can be achieved almost
automatically:
void foo()
{
std::istream infile(whatever);
perform_lots_of_complicated_stuff_which_might_throw;
// the stream will be automatically closed when foo() is exited
// without having to do anything special to achieve that.
}