Garbage collector and real resources

Boris Kolar boris.kolar at globera.com
Wed Jan 24 16:49:27 PST 2007


AlexBurton Wrote:

> Hi,
> 
> First I must confess that I come from C++. I am hoping to move most of my code in the future to D, and am finding it a great language.
> 
> One problem which I hope someone can help me with is where classes reference real resources.
> 
> Here is some example code which I think illustrates my problem
> 
> import std.stream;
> 
> class FileWriter
> {
> 	std.stream.File f;
> 	this()
> 	{
> 		 f = new std.stream.File("data.txt",FileMode.Out);
> 		 f.write(23);
> 	}
> 
> };
> 
> int main()
> {
> 	{
> 		scope auto f = new FileWriter();
> 	}
> 
> 	{
> 		scope auto f = new FileWriter();
> 	}
> 
> 	return 0;
> }
> 
> In this case the FileWriter class uses a real and finite resource (unlike memory which a GC can handle quite well)
> 
> The second instance of FileWriter fails because the first is still around even though the scope keyword is used.
> 
> A solution is to write a destructor for FileWriter that uses the delete keyword (and still use scope).
> Or to leak the close method of the FileStream - and write a try catch block for each level of function call that can exist higher in the stack.
> 
> But what happens if the FileWriter is an aggregate part of another larger class, the explicit destructors and scope decrlarations are leaking the implementation detail that this class has a real resource.
> 
> Also I note that the scope keyword can't be put in class scope ...
> 
> This is a general problem that ties in conceptual constness - it would be nice if there were a way to express that an object is an aggregate part of another.
> 
> Please tell me if I am missing something (including possibly some fundamental GC philosophy)
> 
> Alex

It works as expected for me. This program:

void main() {
	scope class Scope {
		this(char[] foo) {
			printf("Scope.this(\"%s\")\n", foo.ptr);
			_foo = foo;
		}
		~this() {
			printf("Scope.~this(\"%s\")\n", _foo.ptr);
		}
		private char[] _foo;
	}
	printf("Init.\n");
	{
		scope Scope a = new Scope("a");
	}
	printf("Check 1\n");
	{
		scope Scope a = new Scope("b");
	}
	printf("Done.\n");
}

... outputs:
Init.
Scope.this("a")
Scope.~this("a")
Check 1
Scope.this("b")
Scope.~this("b")
Done.



More information about the Digitalmars-d mailing list