digitalmars.D - To copy an auto class
- Arcane Jill (29/29) Jun 08 2004 Auto classes would be a lot more useful if you could copy them. Now, I *...
- Walter (21/50) Jun 08 2004 *do*
- Arcane Jill (23/29) Jun 09 2004 Then the question remains. If I cannot guarantee that a non-auto class w...
- Walter (26/54) Jun 09 2004 when
- Arcane Jill (22/26) Jun 09 2004 You can relax now. Ben Hinkle has completely ended my misunderstanding.
- Walter (11/19) Jun 09 2004 wrong
- Russ Lewis (44/77) Jun 09 2004 It sounds like you need reference counting, but you don't want to call
-
Arcane Jill
(6/9)
Jun 10 2004
In article
, Russ Lewis says... - Russ Lewis (3/3) Jun 10 2004 Doesn't this just imply that 'auto' should instead be 'refcount'? If
- Arcane Jill (11/15) Jun 10 2004 No, I'm afraid it's not going to be that simple. The reason that you can...
- Russ Lewis (11/38) Jun 10 2004 Sorry, I guess I didn't make myself clear. What I meant to suggest was
- Roberto Mariottini (38/42) Jun 11 2004 I was thinking of a way to pass an auto reference to a function.
- Arcane Jill (3/18) Jun 11 2004 Arcane Jill
- Matthew (7/28) Jun 11 2004 AFAIK, that's a well known technique. It's part of D's upholding of the ...
Auto classes would be a lot more useful if you could copy them. Now, I *do* understand the issues here. I've written a lot of explicit memory management stuff in C++. Basically, you need a C++-style copy-constructor. That is, when copying an auto variable from one place to another, you must ensure that a specially written function (copy constructor) is called in which the resource is explicitly reference-counted. The destructor releases the resource only when the number of explicitly counted references reaches zero. This allows you to pass auto variables to functions, and to receive them as return values from functions. This sort of thing can be tedious to write - but sometimes it's the only way to get the job done. ..but that's in C++. In D - well, you can't do it AT ALL. So, what with auto classes not allowing copying, lazy destruction causing the non-auto destructors not to run, and class deallocators apparently being just as lazy as destructors, it would appear that there is NO WAY to manage a resource that you want to be able to copy. Short of writing my own garbage collector, that is. (And freeing module resources at module unload time using static ~this() is an even worse solution). I require a mechanism which will guarantee destruction of a copyable object. There must be a way for D to provide this. I suggest either: (1) an attribute which will cause a class's destructor to run when the gc decides it is time to do so (that is, which requires the gc not to be lazy about this class. (2) a guarantee that class deallocators will always be run, or (3) to allow an auto class to be copied if it has a copy constructor. (I'd even be happy if the compiler required a special keyword such as dont_blame_me_if_it_crashes, to put off the unwary). I hope someone has the heart to do something about this. Arcane Jill
Jun 08 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:ca5i7n$71o$1 digitaldaemon.com...Auto classes would be a lot more useful if you could copy them. Now, I*do*understand the issues here. I've written a lot of explicit memorymanagementstuff in C++. Basically, you need a C++-style copy-constructor. That is, when copying an auto variable from one place to another, you must ensure that a specially written function (copy constructor) is called inwhichthe resource is explicitly reference-counted. The destructor releases the resource only when the number of explicitly counted references reacheszero.This allows you to pass auto variables to functions, and to receive themasreturn values from functions. This sort of thing can be tedious to write - but sometimes it's the onlyway toget the job done. ..but that's in C++. In D - well, you can't do it AT ALL. So, what with auto classes not allowing copying, lazy destruction causingthenon-auto destructors not to run, and class deallocators apparently beingjust aslazy as destructors, it would appear that there is NO WAY to manage aresourcethat you want to be able to copy. Short of writing my own garbage collector, that is. (And freeing module resources at module unload time using static ~this() is an even worsesolution).I require a mechanism which will guarantee destruction of a copyableobject.There must be a way for D to provide this. I suggest either: (1) an attribute which will cause a class's destructor to run when the gc decides it is time to do so (that is, which requires the gc not to be lazyaboutthis class. (2) a guarantee that class deallocators will always be run, or (3) to allow an auto class to be copied if it has a copy constructor. (I'devenbe happy if the compiler required a special keyword such as dont_blame_me_if_it_crashes, to put off the unwary). I hope someone has the heart to do something about this. Arcane JillThere is a misunderstanding here, as the gc *will* call the destructor when an object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it. Next, if one really does need reference counting, just use the AddRef() and Release() protocol used with traditional COM programming. It works, it's just not automatic.
Jun 08 2004
In article <ca69nd$186h$1 digitaldaemon.com>, Walter says...There is a misunderstanding here, as the gc *will* call the destructor when an object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it.Then the question remains. If I cannot guarantee that a non-auto class will not be collected, the problem has not gone away. Either I make a class auto - in which case it (currently) cannont be copied, or I make a class non-auto, in which case it (currently) will not necessarily be properly destroyed. I require a class which I can copy, and for which I can absolutely guarantee destruction. It needs to exist in an application such a server (for which module unload may not happen for months at a time, if at all). My experiments (see separate post) reveal that non-auto objects are quite definitely not always destroyed, so - how do I solve this dilemma? If I have to go so far as writing my own parallel garbage collector, that may be a step too far.Next, if one really does need reference counting, just use the AddRef() and Release() protocol used with traditional COM programming. It works, it's just not automatic.I am writing a security application Walter. It *MUST* be automatic. I will go so far as to lock the data in memory to prevent it from being written to a swap file. I will go so far as to request notification from the operating system before the system hibernates for the same reason. I'm not messing about here. I require that *EITHER* a destructor is guaranteed to be called, *OR* that a custom deallocator is guaranteed to be called, *AND* that such objects may be copied. If you make auto classes copyable, then, believe it or not, that will actually solve the problem. Right now, auto classes are useless for all but the simplest of RAII techniques. Jill
Jun 09 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:ca6tvq$26b9$1 digitaldaemon.com...In article <ca69nd$186h$1 digitaldaemon.com>, Walter says...whenThere is a misunderstanding here, as the gc *will* call the destructorwill notan object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it.Then the question remains. If I cannot guarantee that a non-auto classbe collected, the problem has not gone away. Either I make a class auto - in which case it (currently) cannont becopied, orI make a class non-auto, in which case it (currently) will not necessarilybeproperly destroyed. I require a class which I can copy, and for which I can absolutelyguaranteedestruction. It needs to exist in an application such a server (for whichmoduleunload may not happen for months at a time, if at all). My experiments(seeseparate post) reveal that non-auto objects are quite definitely notalwaysdestroyed, so - how do I solve this dilemma? If I have to go so far aswritingmy own parallel garbage collector, that may be a step too far.Are there any 'sync' points in your app where you know that all outstanding security objects can be cleaned up?andNext, if one really does need reference counting, just use the AddRef()go soRelease() protocol used with traditional COM programming. It works, it's just not automatic.I am writing a security application Walter. It *MUST* be automatic. I willfar as to lock the data in memory to prevent it from being written to aswapfile. I will go so far as to request notification from the operatingsystembefore the system hibernates for the same reason. I'm not messing abouthere. I'm misunderstanding you. If you're writing it, you can completely control the AddRef() and Release() functionality, although the compiler won't do it for you.I require that *EITHER* a destructor is guaranteed to be called, *OR* thatacustom deallocator is guaranteed to be called, *AND* that such objects maybecopied.Do you mean copy the contents of the object, or copy a reference to it?If you make auto classes copyable, then, believe it or not, that willactuallysolve the problem. Right now, auto classes are useless for all but thesimplestof RAII techniques.
Jun 09 2004
In article <ca7m1d$a47$3 digitaldaemon.com>, Walter says...Are there any 'sync' points in your app where you know that all outstanding security objects can be cleaned up?You can relax now. Ben Hinkle has completely ended my misunderstanding. But to answer your question, for any application that I write, yes, I can do that. However, if I just supply a library and OTHER PEOPLE write apps using it, then obviously I can't. But like I said, it doesn't matter now.Do you mean copy the contents of the [auto] object, or copy a reference to it?Well, it's complicated. I meant copy a reference to it. BUT - we're talking RAII classes here, and, as you know, multiple references to the same RAII object cause BIG problems unless you know what you're doing. However - some of us do know what we're doing and are able to manage that complexity, or at least, we could, if the compiler would let us. It would be necessary, when copying a RAII reference, to call some function within the referenced class to "do the right thing" in managing the resource. In C++, that mechanism is the following overload:const T & operator=(const T &);I /totally/ understand why you forbid this. It's the same reason that Java forbids pointers - they're dangerous, people might get it wrong, do the wrong thing and screw up badly. But if D is supposed to let us work under the hood, then maybe, just maybe, you could allow the copying of auto references providing some suitable resource management function was present in the class, and a claas writer knew what they were doing. Just a callback which notified the class that a reference to it was being copied would do the trick. But if you don't want to allow this level of fine control, then, fair enough. Jill
Jun 09 2004
"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:ca7nb2$chc$1 digitaldaemon.com...I /totally/ understand why you forbid this. It's the same reason that Java forbids pointers - they're dangerous, people might get it wrong, do thewrongthing and screw up badly. But if D is supposed to let us work under thehood,then maybe, just maybe, you could allow the copying of auto referencesprovidingsome suitable resource management function was present in the class, and aclaaswriter knew what they were doing. Just a callback which notified the classthata reference to it was being copied would do the trick. But if you don't want to allow this level of fine control, then, fairenough. I think I understand the problem. Let me thing about it for a while. Sometimes, if I let things percolate, I can come up with something (I don't think copy constructors are the right answer).
Jun 09 2004
It sounds like you need reference counting, but you don't want to call AddRef() and RemoveRef() manually. What you want is a reference counting collector. :/ How about this code? I haven't tested it, but I believe that it is more or less what you want. It implements refcounting, with automatic, non-lazy, guaranteed destruction, and it uses 'auto' objects to ensure that you don't forget to remove any references. For even more security, you could declare the Handle class to be auto, forcing ALL instances of it to be auto. class RefCountHandle(T) { RefCountMeta!(T) meta; this(T val) { this.meta = new RefCountMeta!(T); this.meta.val = val; this.meta.refCount = 1; } this(RefCountMeta!(T) meta) { this.meta = meta; meta.refCount++; } ~this() { meta.refCount--; if(meta.refCount == 0) { delete meta.val; delete meta; } } T val() { return meta.val; } RefCountMeta!(T) meta() { return meta; } } class RefCountMeta(T) { T val; int refCount; } void foo() { auto RefCountHandle!(MyClass) secureObj; secureObj = new RefCountHandle!(MyClass)(new MyClass) bar(secureObj.meta); } void bar(RefCountMeta!(MyClass) arg) { auto RefCountHandle!(MyClass) secureObj; secureObj = new RefCountHandle!(MyClass)(arg); } Walter wrote:"Arcane Jill" <Arcane_member pathlink.com> wrote in message news:ca7nb2$chc$1 digitaldaemon.com...I /totally/ understand why you forbid this. It's the same reason that Java forbids pointers - they're dangerous, people might get it wrong, do thewrongthing and screw up badly. But if D is supposed to let us work under thehood,then maybe, just maybe, you could allow the copying of auto referencesprovidingsome suitable resource management function was present in the class, and aclaaswriter knew what they were doing. Just a callback which notified the classthata reference to it was being copied would do the trick. But if you don't want to allow this level of fine control, then, fairenough. I think I understand the problem. Let me thing about it for a while. Sometimes, if I let things percolate, I can come up with something (I don't think copy constructors are the right answer).
Jun 09 2004
In article <ca8uhv$282p$1 digitaldaemon.com>, Russ Lewis says... <clever stuff> Cunning. Of course the same trick looks A LOT neater in C++ where you can overload ->. I've done that sort of thing myself, many a time (just not in D).ptr<T> a; // one of it ptr<T> b = a; // two of it a->f(); // calls T::f() for the instance aBut D's template syntax is a little more cumbersome, and you can't overload ->. Arcane Jill
Jun 10 2004
Doesn't this just imply that 'auto' should instead be 'refcount'? If the compiler implemented refcounting on specially marked variables, then this would be easy...
Jun 10 2004
In article <caabq3$1gpe$1 digitaldaemon.com>, Russ Lewis says...Doesn't this just imply that 'auto' should instead be 'refcount'?No, I'm afraid it's not going to be that simple. The reason that you can't (currently) copy an auto class reference is because it's a very dangerous thing to do. If you're going to do it at all (if Walter lets us), you have to know exactly what you're doing. The compiler won't do reference counting for you. IF that's the appropriate thing to do with a given RAII resource (and it might not be), then you'll have to do it yourself, the hard way.If the compiler implemented refcounting on specially marked variables, then this would be easy...If only. Alas, no compiler can be a mind-reader. :) For non-auto classes of course, we don't need reference counting anyway. The normal behavior of the garbage collected does the same thing only better. Jill
Jun 10 2004
Sorry, I guess I didn't make myself clear. What I meant to suggest was that 'auto' is just a subset of 'refcount'. If you had a 'refcount' variable that never got copied anywhere else, then it would work exactly like 'auto'; it would get deleted when it went out of scope. On the other hand, using 'refcount' lets you copy the reference to other places (like passing it to a function, or even storing it someplace). It means that you can copy references around without the ugliness of the RefCountHandler class I posted above. Russ Arcane Jill wrote:In article <caabq3$1gpe$1 digitaldaemon.com>, Russ Lewis says...Doesn't this just imply that 'auto' should instead be 'refcount'?No, I'm afraid it's not going to be that simple. The reason that you can't (currently) copy an auto class reference is because it's a very dangerous thing to do. If you're going to do it at all (if Walter lets us), you have to know exactly what you're doing. The compiler won't do reference counting for you. IF that's the appropriate thing to do with a given RAII resource (and it might not be), then you'll have to do it yourself, the hard way.If the compiler implemented refcounting on specially marked variables, then this would be easy...If only. Alas, no compiler can be a mind-reader. :) For non-auto classes of course, we don't need reference counting anyway. The normal behavior of the garbage collected does the same thing only better. Jill
Jun 10 2004
In article <caai2r$1qk6$1 digitaldaemon.com>, Arcane Jill says...[...]The reason that you can't (currently) copy an auto class reference is because it's a very dangerous thing to do. If you're going to do it at all (if Walter lets us), you have to know exactly what you're doing.I was thinking of a way to pass an auto reference to a function. Let's suppose that exist a particular type of function parameter, the auto parameter. An auto parameter is particular in the fact that you can't copy the reference to it, just like normal auto references: class MyClass { .. } int f(auto Myclass z, int n) { .. // here you can't take a copy of z } void g() { auto Myclass x = ...; // auto reference Myclass y = ...; // normal reference .. f(x, 2); // it's guaranteed that nobody will take a copy of x .. f(y, 2); // this is good, don't mind if you can/cannot take a copy .. } // here x is destroyed The difference between a regular auto reference it's that the object it's supposed to be already existant _before_ the function call, and it's supposed to be disposed _after_ the function return, when it goes out of its declaration scope. This will permit a certain degree of auto reference copying, while keeping the RAII-consistence. I think that, at a theoretical level, the compiler could infer wheter a parameter is or isn't an auto-parameter based on the following rules: 1 - if the parameter is copied, then it's non-auto 2 - if the parameter id passed as a non-auto function parameter, then it's non-auto 3 - else: it's auto (RAII-safe) I don't know if it can be really done in any case, nor if it's easy to do. Ciao
Jun 11 2004
In article <cacmuo$1qr8$1 digitaldaemon.com>, Roberto Mariottini says...I was thinking of a way to pass an auto reference to a function.You can do that already (but don't tell Walter ;) ).auto class A { uint n; } void incA(A* a) { ++a.n; } int main(char[][] args) { auto A a; incA(&a); return 0; }Arcane Jill
Jun 11 2004
AFAIK, that's a well known technique. It's part of D's upholding of the "Spirit of C" (http://www.comeaucomputing.com/faqs/genfaq.html#betterCgeneral), specifically "Trust the programmer" and "Don't prevent the programmer from doing what needs to be done". Still, it was worth mentioning again... "Arcane Jill" <Arcane_member pathlink.com> wrote in message news:cad2jv$2chs$1 digitaldaemon.com...In article <cacmuo$1qr8$1 digitaldaemon.com>, Roberto Mariottini says...I was thinking of a way to pass an auto reference to a function.You can do that already (but don't tell Walter ;) ).auto class A { uint n; } void incA(A* a) { ++a.n; } int main(char[][] args) { auto A a; incA(&a); return 0; }Arcane Jill
Jun 11 2004