From: tmb@arolla.idiap.ch (Thomas M. Breuel)
Newsgroups: comp.lang.c++
Subject: Re: Garbage Collection for C++
Date: 29 Aug 92 21:48:21 GMT
	<1992Aug25.183619.9541@microsoft.com>
	<DAVEG.92Aug27002517@synaptx.synaptics.com>
	<1992Aug29.054113.917@frumious.uucp>
Reply-To: tmb@idiap.ch
Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
	Perceptive)
In-reply-to: pat@frumious.uucp's message of 29 Aug 92 05:41:13 GMT

In article <1992Aug29.054113.917@frumious.uucp> pat@frumious.uucp (Patrick Smith) writes:

   daveg@synaptics.com (Dave Gillespie) writes:
   |Every third posting in the destruction-of-temporaries thread
   |in this group ends with "if only we had GC so we could solve this
   |problem once and for all..."

   Actually, I don't think adding GC to C++ would solve the problem
   of when to destroy temporaries.

It would help. It wouldn't solve all the problems, and it wouldn't
solve them automatically.

   GC could help with cases such as this:

      String s, t;
      const char* p = (const char*) (s + t);
      // ... do something with p

If GC were added to the C++ language, this would still not work.
You would need to write something like:

	String s,t;
	const char *p = (const char *)new String(s+t);

If you wanted to do something like this frequently, you might be able
to define a class HeapString that eliminates the need for an explicit
call to "new".

   but I don't see how it would help with this:

      ofstream("some_file") << "Hello, " << "world!\n";

This code is wrong, and it would continue to be wrong in the presence
of GC.

As an aside, even in CommonLisp implementations, it is usually bad to
write something like:

	(let ((stream (open ...)))
	   (princ "Hello, world\n" stream))
       
Instead, what you write is:

	(with-open-stream (stream (open ...))
           (princ "Hello, world\n"))

The macro "with-open-stream" makes sure that the stream is closed
immediately when the block is exited.

In fact, the CommonLisp language (last I checked) did not even
guarantee that left-open file descriptors were closed by the GC.

   Well, there is one way.  One could require that all temporaries be
   allocated and destroyed by the garbage collection mechanism.

   There are at least two problems with this:

   1) The destructors for the temporaries are run arbitrarily late,
      if indeed they are ever run (this depends on the rules GC is
      subject to).  In the above example, the programmer probably
      wanted the ofstream destructor to be run fairly soon.

As I have argued before, the GC should not call destructors.  The
primary purpose of GC is to reclaim memory that is not accessible
anymore. All that the GC does, therefore, is give you the illusion
that you have infinite amounts of memory, without any user-visible
effects.

It is usually not the right thing to use the GC to reclaim external
resources that are not accessible anymore, since such resources tend
to be scarce, and (as you also observed) since destruction of such
resources usually does have user-visible effects.

   2) Some (most? almost all?) applications would run more slowly if
      temporaries were allocated from a garbage-collected heap instead
      of from the stack.

Within the constraints of the C++ programming langauge, this is likely
to be true, although there are efficient implementations of
programming languages for which heap allocation is no more costly than
stack allocation.

					Thomas.