March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <spalmer@iname.com> wrote in message news:a70eoj$1ujd$1@digitaldaemon.com... > Destructor semantics are very handy. Let's say I have a 3D Model object > > class Model3D > { > private: > IDirect3DVertexBuffer8* vb; > IDirect3DTexture8* tex; > public: > this() { /+ load model here +/ } > ~this() { vb->Release(); tex->Release(); } > }; > > If your language gives you no guarantees that the destructor will ever get called, you cannot make sure that your program leaves something in a consistent state. You can't use try...finally in the above situation. > > This kind of thing is more common than you think. It's not just mutex's and > memory we have to manage. I understand the problem. What you can do is construct a list of such critical objects, and run the release on them in a finally block off of the program entry point. |
March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:a707f0$1qif$1@digitaldaemon.com... > What this does is add back in C++ semantics for auto-destruction of objects. > Unfortunately, that drags along a great deal of complexity internal to the compiler, coupled with all kinds of obscure rules about when temporaries are > destructed, interactions with various features like ?:, and lots of inevitable obscure implementation bugs. > > Adding this in will mean that D will no longer be a small, easy to understand and implement language. No, no, that wasn't the point. The idea was to add some kind of attribute ("auto"?) for locals that forces them to be deleted immediately when their scope ends. It has nothing to do with temporaries or C++-style stack objects: void foo() { auto File file = new File; ... // file is automatically deleted at the end of function } |
March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | "Pavel Minayev" <evilone@omen.ru> wrote in message news:a71isi$2kvd$1@digitaldaemon.com... > "Walter" <walter@digitalmars.com> wrote in message news:a707f0$1qif$1@digitaldaemon.com... > > What this does is add back in C++ semantics for auto-destruction of > objects. > > Unfortunately, that drags along a great deal of complexity internal to the > > compiler, coupled with all kinds of obscure rules about when temporaries > are > > destructed, interactions with various features like ?:, and lots of > > inevitable obscure implementation bugs. > > Adding this in will mean that D will no longer be a small, easy to > > understand and implement language. > No, no, that wasn't the point. The idea was to add some kind of attribute > ("auto"?) > for locals that forces them to be deleted immediately when their scope ends. > It has nothing to do with temporaries or C++-style stack objects: > void foo() > { > auto File file = new File; > ... > // file is automatically deleted at the end of function > } I think it is analogous to the way C++ calls destructors on stack objects when they go out of scope. The problem isn't that they are on the stack, but the complicated rules for doing the destructors. |
March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:a72klf$6ft$1@digitaldaemon.com... > I think it is analogous to the way C++ calls destructors on stack objects when they go out of scope. The problem isn't that they are on the stack, but > the complicated rules for doing the destructors. What's wrong with the rules? Just destruct the objects in reversed order: File a, b; ... // b destroyed // a destroyed I don't see any complexity here... where am I wrong? |
March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pavel Minayev | "Pavel Minayev" <evilone@omen.ru> wrote in message news:a71isi$2kvd$1@digitaldaemon.com... > "Walter" <walter@digitalmars.com> wrote in message news:a707f0$1qif$1@digitaldaemon.com... > > > > > Adding this in will mean that D will no longer be a small, easy to understand and implement language. > > No, no, that wasn't the point. The idea was to add some kind of attribute > ("auto"?) > for locals that forces them to be deleted immediately when their scope ends. > It has nothing to do with temporaries or C++-style stack objects: > > void foo() > { > auto File file = new File; > ... > // file is automatically deleted at the end of function > } >> Unfortunately, that drags along a great deal of complexity internal to the compiler, coupled with all kinds of obscure rules about when temporaries > are >> destructed, interactions with various features like ?:, and lots of inevitable obscure implementation bugs. >> >> Adding this in will mean that D will no longer be a small, easy to understand and implement language. > > No, no, that wasn't the point. The idea was to add some kind of > attribute ("auto"?) > for locals that forces them to be deleted immediately when their scope > ends. It has nothing to do with temporaries or C++-style stack > objects: > > void foo() > { > auto File file = new File; > ... > // file is automatically deleted at the end of function > } > > I think the problem that Walter has with this is that determining when an object's scope ends is a hard. Just consider looping or try statement scopes with break, continue, return, or goto statements. But I wonder since we are only talking about heap based objects if there is not a easier way to handle this. Consider the following code. int foo() { int doneOnce = 0; lable1: auto File file = new File; for(int i=0; i < 10; ++i) { auto SomeObj a = new SomeObj; if(a.SomeFunc()) continue; auto SomeObj b = new SomeObj; if(b.SomeFunc()) return 1; } if(doneOnce) { doneOnce = 1; goto lable1; } return 2; } Could this be made to work with some very simple rules? 1. Determine all your auto varaibles an initialize them to null at the beginning of the function. 2. Make a cleanup section that deletes all the autos at the end of the function. 3. Every assignment to an auto variable is preceeded by a delete of that object. So the compiler would translate translate the above function into something like this? Assume delete does a null test. int foo() { int rtn; File file = null; SomeObj a = null; SomeObj b = null; int doneOnce = 0; lable1: delete file; file = new File; for(int i=0; i < 10; ++i) { delete a; a = new SomeObj; if(a.SomeFunc()) continue; delete b; b = new SomeObj; if(b.SomeFunc()) { rtn = 1; goto cleanup; } } if(doneOnce) { doneOnce = 1; goto lable1; } rtn = 2; cleanup: delete file; delete a; delete b; return rtn; } Now function calls and return statements need a little consideration. out paramneters are like assignments so rule 3 applies. Since you really can't tell with an inout don't allow it. Don't allow auto variables to be returned for obvious reasons. void FuncIn(in SomeObj a) { } void FuncOut(out SomeObj a) { } void FuncInOut(inout SomeObj a) { } SomeObj foo() { auto SomeObj a = new SomeObj; // This is ok just hope FuncIn doesn't do somthing // silly like store the object or delete it FuncIn(a); // This is ok FuncOut(a); // but a must be deleted before the function call // This is an error can't use auto variables as inout // parameters FuncInOut(a); // This is an error can't return auto variables return a; } |
March 17, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Does that not sound like a gigantic kludge to you? I don't want to be polluting my main() function with stuff that conceptually should be done in a finalize method of an object. Sure we can use delete obj; and manually call the GC when we need to... I would just like some guarantees from the language that the destructor will get called for every object that is collected, and that every object will be collected as the program shuts down. If the compiler could automatically "collect" objects that simply go out of scope when it knows that no pointers to the object have been stored anywhere (the code never takes the address of the object for instance, or never stores it or sends it anywhere), that would be real nice too. Sean "Walter" <walter@digitalmars.com> wrote in message news:a71609$2dcd$1@digitaldaemon.com... > > "Sean L. Palmer" <spalmer@iname.com> wrote in message news:a70eoj$1ujd$1@digitaldaemon.com... > > Destructor semantics are very handy. Let's say I have a 3D Model object > > > > class Model3D > > { > > private: > > IDirect3DVertexBuffer8* vb; > > IDirect3DTexture8* tex; > > public: > > this() { /+ load model here +/ } > > ~this() { vb->Release(); tex->Release(); } > > }; > > > > If your language gives you no guarantees that the destructor will ever get > > called, you cannot make sure that your program leaves something in a consistent state. You can't use try...finally in the above situation. > > > > This kind of thing is more common than you think. It's not just mutex's > and > > memory we have to manage. > > I understand the problem. What you can do is construct a list of such critical objects, and run the release on them in a finally block off of the > program entry point. |
March 18, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Patrick Down | "Patrick Down" <pdown@austin.rr.com> ha scritto nel messaggio news:a72u86$dkt$1@digitaldaemon.com... [...] > > Could this be made to work with some very simple rules? > 1. Determine all your auto varaibles an initialize them to > null at the beginning of the function. > 2. Make a cleanup section that deletes all the autos at > the end of the function. > 3. Every assignment to an auto variable is preceeded by > a delete of that object. It seems to me a good starting point. But how will you deal with exceptions? > So the compiler would translate translate the above function into something like this? Assume delete does a null test. > [... snip code example ...] > > Now function calls and return statements need a little > consideration. out paramneters are like assignments > so rule 3 applies. Since you really can't tell with an > inout don't allow it. Don't allow auto variables to > be returned for obvious reasons. > > > void FuncIn(in SomeObj a) > { > } > > void FuncOut(out SomeObj a) > { > } > > void FuncInOut(inout SomeObj a) > { > } > > SomeObj foo() > { > auto SomeObj a = new SomeObj; > > // This is ok just hope FuncIn doesn't do somthing > // silly like store the object or delete it > FuncIn(a); I can live with this security limitation. > // This is ok > FuncOut(a); > // but a must be deleted before the function call > > // This is an error can't use auto variables as inout > // parameters > FuncInOut(a); Why? > // This is an error can't return auto variables > return a; > } And what if one of theese functions do a "delete" on the auto object? And what about assignments? I mean { auto Object1 a; Object1 b; b = a; Func(b); // storing the pointer? } // now going out of scope... Ciao |
March 18, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote: > I think it is analogous to the way C++ calls destructors on stack objects when they go out of scope. The problem isn't that they are on the stack, but the complicated rules for doing the destructors. Can't we just say that for these types of objects the compiler implicitly generates a finally {} block which deletes them? It does add some complexity, but not much. Compilers that don't support that feature (yet) just throw compile-time errors on the type modifier :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
March 18, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | Russ Lewis wrote:
> Walter wrote:
>
>
>>I think it is analogous to the way C++ calls destructors on stack objects
>>when they go out of scope. The problem isn't that they are on the stack, but
>>the complicated rules for doing the destructors.
>>
>
> Can't we just say that for these types of objects the compiler implicitly
> generates a finally {} block which deletes them? It does add some complexity,
> but not much. Compilers that don't support that feature (yet) just throw
> compile-time errors on the type modifier :)
>
I'll just throw in my $0.02 here -- one of the few
places where C++ really becomes elegant is when you
want to put a resource-grabbing object, or a
debugging object as an auto variable in a function,
and have it naturally cleaned up on function exit.
Reviving C's vestigial "auto" declaration to say
"please destroy at the end of this function/block"
seems like a reasonable way to do this.
-RB
|
March 18, 2002 Re: Force-delete objects? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Roberto Mariottini | ===================================================== "Roberto Mariottini" <rmariottini@lycosmail.com> wrote in news:a74o32$1ne7$1@digitaldaemon.com: > > "Patrick Down" <pdown@austin.rr.com> ha scritto nel messaggio > news:a72u86$dkt$1@digitaldaemon.com... > [...] >> >> Could this be made to work with some very simple rules? >> 1. Determine all your auto varaibles an initialize them to >> null at the beginning of the function. >> 2. Make a cleanup section that deletes all the autos at >> the end of the function. >> 3. Every assignment to an auto variable is preceeded by >> a delete of that object. > > It seems to me a good starting point. But how will you deal with exceptions? Yes, this is a problem. Right now I don't think D needs very complicated code for stack unwinding on an exception. But the auto stuff would require a visit to every frame's cleanup section. >> >> // This is an error can't use auto variables as inout >> // parameters >> FuncInOut(a); > > Why? inout implies that the parameter could be modified. You could do something like this. SomeObj temp = a; FuncInOut(a); if(temp != a) delete temp; > > { > auto Object1 a; > Object1 b; > b = a; > Func(b); // storing the pointer? > } // now going out of scope... I don't have a really good solution for this one and there are many of other ways to get in trouble. For example... Object a = new Object; while(...) { auto Object b = a; // a is deleted after one time // thru the loop } The compiler substitution should be changed to something like this... if(a != b) delete a; a = b; Also you can't do this... auto Object a; auto Object b; a = b; Which means this is a problem... auto Object a; auto Object b; Object c; c = a; b = c; There are many of ways this could go wrong. I guess it depends on if a auto delete pointer is worth all the potential programmer error. |
Copyright © 1999-2021 by the D Language Foundation