views:

711

answers:

4

Please Note: This question is about the difference in terminology between the words "destructor" and "finalizer" and their correct usage. I have merely provided examples of their use in C# and C++/CLI to demonstrate why I am asking the question. I am well aware of how it is implemented in both C# and the CLR, but I am asking about the correct use of terminology.


In the C# world the terms "destructor" and "finalizer" seem to be used pretty much interchangeably, which I suspect is because the C# specification describes the non-deterministic cleanup functionality using the word "destructor", whereas the CLR documentation always uses the word "finalizer", so within the realms of C# they mean the same thing.

However, in the C++/CLI specification there is a distinction made between the two. It allows both deterministic and non-deterministic cleanup, and uses the term "destructor" for the deterministic functionality and "finalizer" for the non-deterministic functionality:

The finalizer provides non-deterministic cleanup. A finalizer is a "last-chance" function that is executed during garbage collection, typically on an object whose destructor was not executed.

Additionally the Wikipedia descriptions of destructor and finalizer indicate that destructors and finalizers are separate concepts, and supports the C++/CLI spec's use of the terms with regard to determinism:

Unlike destructors, finalizers are not deterministic. A destructor is run when the program explicitly frees an object. A finalizer, by contrast, is executed when the internal garbage collection system frees the object.

The questions:

  • Is there, from a computer science point of view, a clearly defined difference between a "destructor" and a "finalizer", or is the terminology something that can only be defined contextually?

  • If there is a clearly defined difference, then why would the C# spec use the 'wrong' terminology?

+2  A: 

I believe 'destructor' is the C# code, and the 'finalizer' is the compiled CIL method. The C# compiler turns a destructor into a finalizer.

EDIT: To be more verbose; The C# language specification defines a 'destructor' as a C# instance method on a class. 'destructor', then, is part of the C# grammar -- destructors are a linguistic object appearing in source code.

A destructor is a member that implements the actions required to destruct an instance of a class. Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be invoked explicitly. The destructor for an instance is invoked automatically during garbage collection.

A 'finalizer' is a term used in the Common Language Runtime, for example in calls to GC.WaitForPendingFinalizers(), and it refers to any .net language, not just C#. Any .net reference type can have a finalizer. For a C# class (the source code artifact), the destructor compiles into the CIL method which is the CLR type's finalizer.

Or more succinctly, destructor is to finalizer as source code is to machine code ;)

Steve Cooper
I know they map to the same thing. I was asking about the correct use of terminology.
Greg Beech
Hi, Greg. I wasn't talking about them mapping to the same thing; where there is a what I meant was that one term refers to a source code artefact, and the other refers to the compiled machine-code artefact. Destructors are mentioned in the C# language spec and are part of the C# grammar; Finalizers are not. However, garbage collection (which is language agnostic) refers to finalizers; eg, in calls like GC.WaitForPendingFinalizers(); thus, Finalizer is a CLR term, and refers to the process of cleaning up before releasing memory of a .net object. I'll try to edit my post to clarify it there, too
Steve Cooper
C# does not have destructors, only finalizers. The fact that it shares a similar syntax to C++'s destructor does not matter.
sixlettervariables
We're probably violently agreeing here. C#'s destructors don't do what C++'s destructors do. They aren't the same thing. But the spec _defines_ the word 'destructor' in the context of the C# language, so it certainly has them. They just have nothing to do with the C++ concept.
Steve Cooper
+2  A: 

If we abide to the "deterministic" definition of destructors, then I would say that in .NET objects have no destructors unless explicitly implemented by using the IDisposable interface.

Konamiman
+4  A: 

Strictly speaking C# doesn't have a destructor (I believe the C# spec is confusing on this point). C#'s finalizer looks like a C++ destructor but, as you say, is non-deterministic. C# has deterministic clean-up in the form of IDisposable::Dispose (but this is still not called a destructor).

C++/CLI has deterministic destructors, which look like C++ destructors. At the CLI level these map onto IDisposable::Dispose() (IDisposable is implemented for you ). C++/CLI has non-deterministic finalizers, which look like destructors but use the ! prefix instead of the ^ prefix.

The fact that C++/CLI uses the same syntax for destructors that C# uses for finalizers can be a little confusing - but it fits better with C++, which has a strong tradition of deterministic destruction.

Unfortunately the lack of universal definitions of these terms means you always need to clarify what you are talking about. Personally I always use the word finalizer when talking about the C# concept and reserve destructor for contexts where it definitely implies deterministic destruction.

[Update] Since my original post here Eric Lippert has posted his response (the accepted answer) and followed up with a blog post on the same. I'm glad to see we're in agreement :-)

Phil Nash
The 'problem' is that C# does call it a destructor.
Henk Holterman
Yes, I recalled that after I first answered - it uses both terms - hence my added comment about it being confusing. It's both clearer and still correct to call them finalizers.
Phil Nash
+1 I think this is the best answer. Looks like the C# spec is a bit misleading with its terms. Maybe it was written by an intern :P
SwDevMan81
In the C# 3.5 definition, there is no use of the word 'finalizer' -- just the word 'destructor', which is defined as "a member that implements the actions required to destruct an instance of a class" C# does have destructors, and not finalizers. It's the CLR that has finalizers.
Steve Cooper
@Steve You are correct that the C# spec refers to the language feature as a destructor, which implements the finalizer concept. I still say this is confusing.
Phil Nash
Then I suggest never calling C#'s finalizers "destructors" and you will never have the confusion.
sixlettervariables
@sixlettervariables - agreed :-)
Phil Nash
+13  A: 

1) Is there a well-defined difference between "destructor" and "finalizer" as used in industry or academia?

There certainly appears to be. The difference seems to be that destructors are cleanup methods that are invoked deterministically, whereas finalizers run when the garbage collector tells them to.

2) In that case, the C# spec gets it wrong -- finalizers are called "destructors" in C#. Why did the authors of the C# spec get it wrong?

I don't know, but I can guess. In fact, I have two guesses.

Guess #1 is that on May 12th, 1999 there was not a wikipedia article clearly describing the subtle difference between these two concepts. That's because there wasn't a wikipedia. Remember back when there wasn't a wikipedia? Dark ages, man. The error might simply have been an honest mistake, believing that the two terms were identical.

Heck, for all I know, the two terms were identical on May 12th, 1999, and the difference in definitions only evolved later, as it became obvious that there was a need to disambiguate between eager and lazy cleanup methods.

Guess #2 is that on May 12th, 1999, the language design committee wished to leave open the possibility that a "destructor" could be implemented as something other than a finalizer. That is, the "destructor" was designed to be a C# language concept that did not necessarily map one-to-one with the .NET "finalizer" concept. When designing a language at the same time as the framework it sits atop is also being designed, sometimes you want to insulate yourself against late-breaking design changes in your subsystems.

The language committee's notes for May 12th 1999 read in part:

We're going to use the term "destructor" for the member which executes when an instance is reclaimed. Classes can have destructors; structs can't. Unlike in C++, a destructor cannot be called explicitly. Destruction is non-deterministic – you can't reliably know when the destructor will execute, except to say that it executes at some point after all references to the object have been released. The destructors in an inheritance chain are called in order, from most descendant to least descendant. There is no need (and no way) for the derived class to explicitly call the base destructor. The C# compiler compiles destructors to the appropriate CLR representation. For this version that probably means an instance finalizer that is distinguished in metadata. CLR may provide static finalizers in the future; we do not see any barrier to C# using static finalizers.

So, there, you now know everything I know on the subject. If you want to know more, ask Anders next time you see him.

Eric Lippert
Interesting; from the notes it certainly sounds like at the time destructor did not imply determinism so I reckon you're probably right that it's a distinction that has evolved since.
Greg Beech