Thread overview | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 11, 2010 [Issue 4621] New: Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=4621 Summary: Destructors are inherently un-@safe Product: D Version: D2 Platform: All OS/Version: All Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: michel.fortin@michelf.com --- Comment #0 from Michel Fortin <michel.fortin@michelf.com> 2010-08-11 14:08:33 EDT --- Accessing the GC heap through a member in a destructors is inherently unsafe because the GC might have already freed that memory. So destructors in SafeD should not be able to access the GC-heap through a member. Here is an example: @safe: class C { C other; ~this() { writeln(other.toString()); // "other" might already have been freed. } } void main() { C c1 = new C; C c2 = new C; c1.other = c2; c2.other = c1; // creating a circular reference } Given that the compiler has no way to know if a reference, pointer, or array points to the GC heap or elsewhere, it might have to disallow any dereferencing of any member and calls to functions that might dereference a member. And at this point you can't do anything useful in a destructor, so you might just disallow @safe destructors altogether. Note that this applies to struct destructors too, since structs can be on the heap (in their own memory block, part of an array, or as a member of a class). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 Jonathan M Davis <jmdavisProg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jmdavisProg@gmail.com --- Comment #1 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-11 11:36:33 PDT --- What about structs which are on the stack? I agree that the stuff on the heap has this problem, but structs on the stack should be fine, shouldn't they? I'd hate for structs on the stack not be able to have destructors except in SafeD. It would make RAII only work in SafeD, which would not be good. I do agree that destructors on the heap should be disallowed in SafeD, but I don't want to see structs on the heap not being allowed to have destructors in SafeD. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #2 from Michel Fortin <michel.fortin@michelf.com> 2010-08-11 14:37:52 EDT --- Perhaps a better solution for structs: have a way to distinguish between a struct that can be put on the GC heap and one that cannot. A struct that cannot go on the GC heap make it safe to access GC-managed members in its destructor, and thus can have a @safe destructor. But at the same time such a struct would be prohibited at compile time from being part of a class, or from being allocated with "new" (either solitary or part of an array). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #3 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-11 11:43:00 PDT --- Ouch. That last sentence of my needs editing. I meant to say that I don't want to see structs on the _stack_ not being allowed to have destructors in SafeD. But obviously you understood what I meant. As for your suggestion, couldn't the compiler just disallow structs with destructors from anywhere but the stack in SafeD? If you try and declare them anywhere else, you'd get an error. There shouldn't be any need to distinguish them otherwise. The destructor itself could do that. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #4 from Michel Fortin <michel.fortin@michelf.com> 2010-08-11 15:33:11 EDT --- The problem with structs is that many structs will need a destructor because they encapsulate a resource not managed by the GC. That destructor can be made GC-heap safe, and thus this struct can be put in a class. For instance, a File struct wrapping a file handle could easily be made GC-heap safe if it's destructor just calls fclose(handle), and thus could be put in a class. Are you willing to make this File struct unusable in SafeD? Or std.container.Array, which is totally safe to use on the heap too? So I think there is a need to distinguish GC-safe structs from those that aren't. Forbidding all structs with a destructor to be put on the heap in SafeD is going to prevent too many useful things. Obviously, the struct itself would need a @trusted destructor. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #5 from Jonathan M Davis <jmdavisProg@gmail.com> 2010-08-11 13:10:28 PDT --- This mess is just too complicated. Sigh. Well, we want to be able to use structs with destructors in SafeD wherever is reasonable to use them, and those uses should be allowed. Unsafe uses should not be allowed. If attributes of some kind are required on the structs or their destructors to make it work, then that's the path that we should take. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 11, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #6 from Michel Fortin <michel.fortin@michelf.com> 2010-08-11 16:20:44 EDT --- It could be an attribute, or it could be something else. For instance, instead of having just destructors, we could have destructors (~this) and finalizers (~~this). A struct with neither can go anywhere, a struct with a destructor but no finalizer cannot go on the GC-heap, a struct with only a finalizer can go anywhere (the finalizer is used as the destructor), and a struct with both can go anywhere. The finalizer cannot be made @safe. Doing this with structs would probably mean allowing only finalizers (~~this) for classes, which according to my syntax suggestion would break existing code for class destructors. Perhaps the syntax should be different. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 12, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 Steven Schveighoffer <schveiguy@yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy@yahoo.com --- Comment #7 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-08-12 05:21:10 PDT --- (In reply to comment #6) > It could be an attribute, or it could be something else. > > For instance, instead of having just destructors, we could have destructors (~this) and finalizers (~~this). A struct with neither can go anywhere, a struct with a destructor but no finalizer cannot go on the GC-heap, a struct with only a finalizer can go anywhere (the finalizer is used as the destructor), and a struct with both can go anywhere. The finalizer cannot be made @safe. I think rather than prevent where these items should go, you should just not call the destructor when the struct/class is being destroyed by the GC. I'd say you could even prevent what the finalizer contains, but it's too limiting for the compiler to assume what type of memory a reference is referencing. My thought is simply that a finalizer is not safe, and a destructor is safe. That at least gives a path for implementation (just mark your finalizer as @trusted, and it can be used in SafeD). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 12, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 nfxjfg@gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |nfxjfg@gmail.com --- Comment #8 from nfxjfg@gmail.com 2010-08-12 06:20:27 PDT --- *facepalm* C# and Java have safe finalizers. There's nothing that stops you rewriting the finalization part in gcx.d to make it safe. The only real issue is that finalizers are not deterministic (unsolvable) and that finalizers are invoked in an arbitrary context (solvable if you'd create a finalization worker thread or so). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 12, 2010 [Issue 4621] Destructors are inherently un-@safe | ||||
---|---|---|---|---|
| ||||
Posted in reply to Michel Fortin | http://d.puremagic.com/issues/show_bug.cgi?id=4621 --- Comment #9 from Michel Fortin <michel.fortin@michelf.com> 2010-08-12 09:37:20 EDT --- (In reply to comment #7) > I think rather than prevent where these items should go, you should just not call the destructor when the struct/class is being destroyed by the GC. One thing is that I fear it becomes too easy to write a destructor and then forget the finalizer, which would results in leaks everywhere. So I think there has to be something to remind people that they need a finalizer when they need to dispose of some resource and the struct is allocated on the heap. But just not calling the finalizer is still a better option than calling the destructor during collection: a leak is less harmful than memory corruption. Forbidding GC-allocated structs could be useful to make some RAII patterns safer too. For instance, think of a struct representing a database transaction: it should probably live on the stack, you certainly don't want it to be garbaged collected. The compiler enforcing deterministic destruction would improve program correctness for this kind of thing. > I'd say you could even prevent what the finalizer contains, but it's too limiting for the compiler to assume what type of memory a reference is referencing. My thought is simply that a finalizer is not safe, and a destructor is safe. That at least gives a path for implementation (just mark your finalizer as @trusted, and it can be used in SafeD). Whatever it is, I'm now of the opinion that the limitation should only apply to SafeD. The limitation could be about dereferencing members and calling functions that might dereference a member, or it could be that the finalizer itself is not allowed to be safe. Allowing non-dereferencing actions in the finalizer in SafeD would still allow a few things, such as printing a "Hello I'm finalized!" message on the console or updating a global variable (such as a counter of live objects). Nothing very interesting though. But it'd also allow an empty finalizer to be @safe, which might be useful if the presence of a destructor and the absence of a finalizer prevents allocation on the GC-heap. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation