> I believe the main difficulty comes from heading into uncharted waters.
For
> example, once you've decided to make garbage collection optional, what
does
> the following line of code mean?
> 
>      delete x;

If the above code is compiled to Parrot, it probably equivalent to

  x->~Destructor();

i.e., the destructor is called, but the memory is left to GC, which most
likely
handle free at a later time.

> Or, for example, are the side effects of the following two functions
> different?
> 
> void f1()
> {
>      // On the stack
>      MyClass o;
> }
> 
> void f2()
> {
>      // On the heap
>      MyClass o = new MyClass();
> }
> 
> If garbage collection is not 100% deterministic, these two functions could
> produce very different results because we do not know when or if the
> destructor for MyClass will execute in the case of f2().

This is exactly the same case for C++. When you compile f2 with gcc, how
can you tell when the destructor is called. Even the following code does
not work.

  void f3()
  {
    MyClass o = new MyClass();
    ...
    delete o;
  }

If there is an exception happens within (...), the destructor will not be
called.

> If garbage collection is
> not 100% deterministic (and Mark and Sweep is not), we need extra language
> features, such as Java's "finally" block, to ensure things can be cleaned
> up, and extra training to ensure programmers are smart enough to know how
> to use "finally" blocks correctly.

That is exactly the case for C++. In your above code f1(), the C++ compiler
already (behind the scene) inserts finally block for "o" destructor. That
is why the destructor of stack allocated objects is called even when
exception 
happens. The only difference is that the memory deallocation is
dis-associated
with object destruction.

Summary: the object destruction with GC is as deterministic as C++ heap 
allocated object, i.e. you have to call "delete x" (in C++), x.close() (in
Java), x.dispose (in C#), otherwise is 0% deterministic, period.

Hong

Reply via email to