digitalmars.D - Destroying structs (literally)
- Andrei Alexandrescu (9/9) Aug 28 2014 Dear community, are you ready for this?
- Orvid King (8/17) Aug 28 2014 There should be no breaking behavior, provided the code was previously
- H. S. Teoh via Digitalmars-d (9/18) Aug 28 2014 Let's do it. Issue 2834 was filed in 2009. It's almost winning the
- monarch_dodra (9/13) Aug 28 2014 Well, this new change *could* greatly increase the amount of
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (8/21) Aug 29 2014 Jacob Carlborg just recently brought this up in another thread.
- Jacob Carlborg (5/11) Aug 29 2014 Yeah, Tango for D1 added a new method, "dispose", to Object. It's called...
- Andrei Alexandrescu (3/9) Aug 29 2014 I think we need to stay with what we have. Adding a distinct kind of
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (15/30) Aug 29 2014 Our idea was that an additional destructor (let's call it a
- Orvid King (9/33) Aug 29 2014 I would say that all of those restrictions, except for nothrow, are
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (18/72) Aug 30 2014 Hmmm... could the GC zero those references that it already
- Orvid King (9/63) Aug 30 2014 The references issue can be gotten around by marking an allocation that
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (21/123) Aug 30 2014 The problem is not only dereferencing those pointers (though
- Orvid King (7/25) Aug 30 2014 It's perfectly fine to not be able to guarantee the order of the
- deadalnix (3/12) Aug 28 2014 I have no idea what the decision is.
- Jonathan M Davis (16/23) Aug 28 2014 It will _fix_ a lot of code, I expect, whereas it will probably
- Brad Roberts via Digitalmars-d (3/12) Aug 28 2014 I didn't study the changes, except to note that the number of tests
- Brad Roberts via Digitalmars-d (2/4) Aug 28 2014 Er: rather LOW considering...
- Dicebot (5/14) Aug 28 2014 I think providing rollback transition flag is simply a matter of
- Jonathan M Davis (11/31) Aug 28 2014 Since this is in the library, not the compiler, I'm not sure how
- Andrei Alexandrescu (5/11) Aug 28 2014 I'd say the impact is too large to leave things at that. How about a
- Jonathan M Davis (6/22) Aug 28 2014 I'm okay with that, though given that this is almost exclusively
- Dicebot (6/8) Aug 28 2014 Exactly the culture I am trying to change here.
- Brian Schott (3/4) Aug 28 2014 Yes.
- monarch_dodra (10/19) Aug 28 2014 Questions:
- Orvid King (10/18) Aug 29 2014 Yes, this does work for arrays of structs. Provided that you've passed
- monarch_dodra (18/39) Aug 29 2014 Hum... by "manual" memory allocation. I meant this:
- monarch_dodra (18/39) Aug 29 2014 Hum... by "manual" memory allocation. I meant this:
- Jacob Carlborg (5/8) Aug 28 2014 Does this has the same issues as destructors for classes, i.e. not
- ketmar via Digitalmars-d (4/5) Aug 28 2014 On Thu, 28 Aug 2014 19:21:04 -0700
- Andrei Alexandrescu (2/7) Aug 29 2014 You forgot the Oxford comma :o). -- Andrei
- ketmar via Digitalmars-d (5/7) Aug 29 2014 On Fri, 29 Aug 2014 09:49:07 -0700
- ponce (3/4) Aug 29 2014 Yes! Whatever needs be done.
- Andrej Mitrovic via Digitalmars-d (3/7) Aug 29 2014 Yeah destructors are a sore pain when they're unreliable. "May or may
- monarch_dodra (7/17) Aug 29 2014 That won't really change though, will it? AFAIK, it'll become:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (2/20) Aug 29 2014 Yes, there's no way around this with a conservative GC.
- Andrei Alexandrescu (2/18) Aug 29 2014 Right, and reasonable. -- Andrei
- Peter Alexander (5/8) Aug 29 2014 Yes.
- John Colvin (2/10) Aug 29 2014 Especially seeing as now we are doing patch releases.
Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, Andrei
Aug 28 2014
On 8/28/2014 9:21 PM, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiThere should be no breaking behavior, provided the code was previously calling destroy, and not simply manually calling the destructor directly for a heap allocated struct, as I've had to make sure that it's not called more than once, otherwise the existing unittests wouldn't pass. The only potentially breaking change introduced in this, which was previously present in one of the struct destructor tests, is that allocating in the heap allocated struct's destructor isn't allowed.
Aug 28 2014
On Thu, Aug 28, 2014 at 07:21:04PM -0700, Andrei Alexandrescu via Digitalmars-d wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067?Let's do it. Issue 2834 was filed in 2009. It's almost winning the longest-open-bug award. It's about time we did something.This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it?[...] Maybe a more relevant question might be, is there any existing code that *isn't* broken by structs not being destructed? (D-structed, har har.) T -- If I were two-faced, would I be wearing this one? -- Abraham Lincoln
Aug 28 2014
On Friday, 29 August 2014 at 02:38:54 UTC, H. S. Teoh via Digitalmars-d wrote:Maybe a more relevant question might be, is there any existing code that *isn't* broken by structs not being destructed? (D-structed, har har.)Well, this new change *could* greatly increase the amount of "allocation during destruction" errors we are getting. I've seen a fair share of these in learn, whereas a class destructor allocates. Structs will now also be more vulnerable to this problem too. I wouldn't be surprised if this pull instantaneously introduced a fair amount of breakage in client code.
Aug 28 2014
On Friday, 29 August 2014 at 06:39:20 UTC, monarch_dodra wrote:On Friday, 29 August 2014 at 02:38:54 UTC, H. S. Teoh via Digitalmars-d wrote:Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.Maybe a more relevant question might be, is there any existing code that *isn't* broken by structs not being destructed? (D-structed, har har.)Well, this new change *could* greatly increase the amount of "allocation during destruction" errors we are getting. I've seen a fair share of these in learn, whereas a class destructor allocates. Structs will now also be more vulnerable to this problem too. I wouldn't be surprised if this pull instantaneously introduced a fair amount of breakage in client code.
Aug 29 2014
On 29/08/14 12:53, "Marc Schütz" <schuetzm gmx.net>" wrote:Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.Yeah, Tango for D1 added a new method, "dispose", to Object. It's called when "delete" or "scope" is used. -- /Jacob Carlborg
Aug 29 2014
On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 29 2014
On Friday, 29 August 2014 at 19:01:51 UTC, Andrei Alexandrescu wrote:On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Our idea was that an additional destructor (let's call it a finalizer) would be helpful because it is backward compatible. The compiler could make some validity checks on it, at the least make it nothrow, maybe nogc (but I believe we can relax this restriction), pure (?). Disallowing access to references (because they could pointer to already destroyed objects) is unfortunately not feasible, because we can't distinguish GC pointers from other ones. To avoid the need for code duplication, finalizers could always be called implicitly by destructors (assuming everything that is allowed in finalizers is also permitted in destructors). Calling destructors from the GC could later be phased out. It is technically not a breaking change, because there never was a guarantee that they'd be called anyway.Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 29 2014
On 8/29/2014 2:52 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:On Friday, 29 August 2014 at 19:01:51 UTC, Andrei Alexandrescu wrote:I would say that all of those restrictions, except for nothrow, are dependent on the current GC implementation. It is possible to write the GC in such a way that you can do GC allocations in a destructor, as well as access any GC references you want. The only thing with the GC references is that there's no way to guarantee that the referenced objects won't have already had their destructor called when the current destructor is being called.On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Our idea was that an additional destructor (let's call it a finalizer) would be helpful because it is backward compatible. The compiler could make some validity checks on it, at the least make it nothrow, maybe nogc (but I believe we can relax this restriction), pure (?). Disallowing access to references (because they could pointer to already destroyed objects) is unfortunately not feasible, because we can't distinguish GC pointers from other ones. To avoid the need for code duplication, finalizers could always be called implicitly by destructors (assuming everything that is allowed in finalizers is also permitted in destructors). Calling destructors from the GC could later be phased out. It is technically not a breaking change, because there never was a guarantee that they'd be called anyway.Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 29 2014
On Saturday, 30 August 2014 at 03:54:41 UTC, Orvid King wrote:On 8/29/2014 2:52 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:Hmmm... could the GC zero those references that it already destroyed, before calling the finalizer? Don't know how this would affect performance, but it would only be necessary if a finalizer exists (could even be restricted to those references that are accessible from non-trivial finalizers, i.e. if a struct has GCed pointers and an embedded struct member with a finalizer, but no finalizer of its own, the compiler would probably generate one that only calls the member's finalizer, but this would have no access to its parent's pointers). You're right that many of the restrictions are only necessary because of the current GC implementation. Even the fact that garbage collection can happen in any thread could theoretically be changed. Even more complicated: I can imagine that with the upcoming allocator work there could be several different GC implementations, even used in parallel in the same program, each with different capabilities and restrictions. It's clear that this requires coordination.On Friday, 29 August 2014 at 19:01:51 UTC, Andrei Alexandrescu wrote:I would say that all of those restrictions, except for nothrow, are dependent on the current GC implementation. It is possible to write the GC in such a way that you can do GC allocations in a destructor, as well as access any GC references you want. The only thing with the GC references is that there's no way to guarantee that the referenced objects won't have already had their destructor called when the current destructor is being called.On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Our idea was that an additional destructor (let's call it a finalizer) would be helpful because it is backward compatible. The compiler could make some validity checks on it, at the least make it nothrow, maybe nogc (but I believe we can relax this restriction), pure (?). Disallowing access to references (because they could pointer to already destroyed objects) is unfortunately not feasible, because we can't distinguish GC pointers from other ones. To avoid the need for code duplication, finalizers could always be called implicitly by destructors (assuming everything that is allowed in finalizers is also permitted in destructors). Calling destructors from the GC could later be phased out. It is technically not a breaking change, because there never was a guarantee that they'd be called anyway.Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 30 2014
On 8/30/2014 4:22 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:On Saturday, 30 August 2014 at 03:54:41 UTC, Orvid King wrote:The references issue can be gotten around by marking an allocation that needs finalization as if it were alive. It does mean however that finalizable allocations will live through more than one collection. I believe this is how .Net currently handles them, as I don't remember anything in the spec about restrictions on what's referenced in destructors, nor have I had issues referencing otherwise dead allocations in them.On 8/29/2014 2:52 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:Hmmm... could the GC zero those references that it already destroyed, before calling the finalizer? Don't know how this would affect performance, but it would only be necessary if a finalizer exists (could even be restricted to those references that are accessible from non-trivial finalizers, i.e. if a struct has GCed pointers and an embedded struct member with a finalizer, but no finalizer of its own, the compiler would probably generate one that only calls the member's finalizer, but this would have no access to its parent's pointers). You're right that many of the restrictions are only necessary because of the current GC implementation. Even the fact that garbage collection can happen in any thread could theoretically be changed. Even more complicated: I can imagine that with the upcoming allocator work there could be several different GC implementations, even used in parallel in the same program, each with different capabilities and restrictions. It's clear that this requires coordination.On Friday, 29 August 2014 at 19:01:51 UTC, Andrei Alexandrescu wrote:I would say that all of those restrictions, except for nothrow, are dependent on the current GC implementation. It is possible to write the GC in such a way that you can do GC allocations in a destructor, as well as access any GC references you want. The only thing with the GC references is that there's no way to guarantee that the referenced objects won't have already had their destructor called when the current destructor is being called.On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Our idea was that an additional destructor (let's call it a finalizer) would be helpful because it is backward compatible. The compiler could make some validity checks on it, at the least make it nothrow, maybe nogc (but I believe we can relax this restriction), pure (?). Disallowing access to references (because they could pointer to already destroyed objects) is unfortunately not feasible, because we can't distinguish GC pointers from other ones. To avoid the need for code duplication, finalizers could always be called implicitly by destructors (assuming everything that is allowed in finalizers is also permitted in destructors). Calling destructors from the GC could later be phased out. It is technically not a breaking change, because there never was a guarantee that they'd be called anyway.Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 30 2014
On Saturday, 30 August 2014 at 15:18:52 UTC, Orvid King wrote:On 8/30/2014 4:22 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:The problem is not only dereferencing those pointers (though depending on how the GC works even this might be racy, i.e. the memory location could have been reused already), but that a destructor/finalizer already ran on the referenced object. It is thus potentially in an invalid state. Even copying it is dangerous, because you're then creating a live object from that invalid state which will itself be destroyed again at some point. This might lead to double frees of depending manually allocated objects, or potentially other problems. Then there's the possibility to "resurrect" such an object by storing a reference to it somewhere else during finalization. Doing the scanning and finalization separately like this is _probably_ safe: 1. Marking phase as usual. 2. Select the objects that have a finalizer, and clear all references in them that point to objects that are now unreachable. (This requires a precise GC.) 3. Call the finalizers. Not sure what to do about things that may or may not be references.On Saturday, 30 August 2014 at 03:54:41 UTC, Orvid King wrote:The references issue can be gotten around by marking an allocation that needs finalization as if it were alive. It does mean however that finalizable allocations will live through more than one collection. I believe this is how .Net currently handles them, as I don't remember anything in the spec about restrictions on what's referenced in destructors, nor have I had issues referencing otherwise dead allocations in them.On 8/29/2014 2:52 PM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:Hmmm... could the GC zero those references that it already destroyed, before calling the finalizer? Don't know how this would affect performance, but it would only be necessary if a finalizer exists (could even be restricted to those references that are accessible from non-trivial finalizers, i.e. if a struct has GCed pointers and an embedded struct member with a finalizer, but no finalizer of its own, the compiler would probably generate one that only calls the member's finalizer, but this would have no access to its parent's pointers). You're right that many of the restrictions are only necessary because of the current GC implementation. Even the fact that garbage collection can happen in any thread could theoretically be changed. Even more complicated: I can imagine that with the upcoming allocator work there could be several different GC implementations, even used in parallel in the same program, each with different capabilities and restrictions. It's clear that this requires coordination.On Friday, 29 August 2014 at 19:01:51 UTC, Andrei Alexandrescu wrote:I would say that all of those restrictions, except for nothrow, are dependent on the current GC implementation. It is possible to write the GC in such a way that you can do GC allocations in a destructor, as well as access any GC references you want. The only thing with the GC references is that there's no way to guarantee that the referenced objects won't have already had their destructor called when the current destructor is being called.On 8/29/14, 3:53 AM, "Marc Schütz" <schuetzm gmx.net>" wrote:Our idea was that an additional destructor (let's call it a finalizer) would be helpful because it is backward compatible. The compiler could make some validity checks on it, at the least make it nothrow, maybe nogc (but I believe we can relax this restriction), pure (?). Disallowing access to references (because they could pointer to already destroyed objects) is unfortunately not feasible, because we can't distinguish GC pointers from other ones. To avoid the need for code duplication, finalizers could always be called implicitly by destructors (assuming everything that is allowed in finalizers is also permitted in destructors). Calling destructors from the GC could later be phased out. It is technically not a breaking change, because there never was a guarantee that they'd be called anyway.Jacob Carlborg just recently brought this up in another thread. Isn't it kind of consensus that calling a destructor from the GC is not a good idea because of the restrictions that apply in this context? Andrei even wanted to deprecate destructors for classes because of this. Maybe a better direction would be to separate the concepts of destruction and finalization, and introduce two kinds of "destructors" for them.I think we need to stay with what we have. Adding a distinct kind of destructor might be interesting. -- Andrei
Aug 30 2014
On 8/30/2014 10:35 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net>" wrote:The problem is not only dereferencing those pointers (though depending on how the GC works even this might be racy, i.e. the memory location could have been reused already), but that a destructor/finalizer already ran on the referenced object. It is thus potentially in an invalid state. Even copying it is dangerous, because you're then creating a live object from that invalid state which will itself be destroyed again at some point. This might lead to double frees of depending manually allocated objects, or potentially other problems. Then there's the possibility to "resurrect" such an object by storing a reference to it somewhere else during finalization. Doing the scanning and finalization separately like this is _probably_ safe: 1. Marking phase as usual. 2. Select the objects that have a finalizer, and clear all references in them that point to objects that are now unreachable. (This requires a precise GC.) 3. Call the finalizers. Not sure what to do about things that may or may not be references.It's perfectly fine to not be able to guarantee the order of the finalization, but we can guarantee that the values referenced by the allocation being finalized are still allocated. It's up to the user to understand that the finalizable object they are trying to reference in their destructor may already have been finalized.
Aug 30 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiI have no idea what the decision is.
Aug 28 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it?It will _fix_ a lot of code, I expect, whereas it will probably break very little. The main thing that it would break would be if there's any GC heap allocation in a struct's destructor, but that will only matter if the struct is on the GC heap, and I think that it's something that we're pretty much stuck with. Certainly, that's not much of a loss in comparison to all of the bugs created by stuff like an array of std.stdio.Files. Maybe there's a problem if someone was manually destroying stuff? But if so, I don't see how we can avoid breaking their code. And they'll probably be much happier with this change just so long as they're aware of it, and hopefull the changelog is enough for that. So, I'd say to put it in 2.067. I don't think that waiting buys us anything. - Jonathan M Davis
Aug 28 2014
On 8/28/2014 7:21 PM, Andrei Alexandrescu via Digitalmars-d wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiI didn't study the changes, except to note that the number of tests seems rather considering the nature of what's changing.
Aug 28 2014
On 8/28/2014 7:54 PM, Brad Roberts via Digitalmars-d wrote:I didn't study the changes, except to note that the number of tests seems rather considering the nature of what's changing.Er: rather LOW considering...
Aug 28 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiI think providing rollback transition flag is simply a matter of politeness even if in this specific case it makes no sense to rely on existing broken behavior.
Aug 28 2014
On Friday, 29 August 2014 at 02:59:07 UTC, Dicebot wrote:On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Since this is in the library, not the compiler, I'm not sure how you'd do that (have the compiler specific a version identifier for it?), but considering how broken the behavior was before and that we don't normally provide flags to revert changes in behavior, I'd argue that anyone who has problems with it should just use the previous version of the compiler until they're ready to update their code. It's not like we want to support the old behavior for any real period of time anyway. It's just plain broken. - Jonathan M DavisDear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiI think providing rollback transition flag is simply a matter of politeness even if in this specific case it makes no sense to rely on existing broken behavior.
Aug 28 2014
On 8/28/14, 8:07 PM, Jonathan M Davis wrote:Since this is in the library, not the compiler, I'm not sure how you'd do that (have the compiler specific a version identifier for it?), but considering how broken the behavior was before and that we don't normally provide flags to revert changes in behavior, I'd argue that anyone who has problems with it should just use the previous version of the compiler until they're ready to update their code.I'd say the impact is too large to leave things at that. How about a function call callStructDestructorsDuringGC(bool) - yes, that long - that people can place in main() if they're having trouble? Andrei
Aug 28 2014
On Friday, 29 August 2014 at 03:32:45 UTC, Andrei Alexandrescu wrote:On 8/28/14, 8:07 PM, Jonathan M Davis wrote:I'm okay with that, though given that this is almost exclusively fixing bugs and isn't particularly likely to create many, I'm not at all convinced that it's that big a deal. - Jonathan M DavisSince this is in the library, not the compiler, I'm not sure how you'd do that (have the compiler specific a version identifier for it?), but considering how broken the behavior was before and that we don't normally provide flags to revert changes in behavior, I'd argue that anyone who has problems with it should just use the previous version of the compiler until they're ready to update their code.I'd say the impact is too large to leave things at that. How about a function call callStructDestructorsDuringGC(bool) - yes, that long - that people can place in main() if they're having trouble?
Aug 28 2014
On Friday, 29 August 2014 at 03:07:06 UTC, Jonathan M Davis wrote:and that we don't normally provide flags to revert changes in behaviorExactly the culture I am trying to change here. Either companion flag in compiler that prints places where structs are going to be "destructored" now or runtime switch for druntime that disable new behavior if set. Pretty much anything that can show users that we care.
Aug 28 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this?Yes.
Aug 28 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864 We must do it, and the way I see it the earlier the better. Shall we do it in 2.067? This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it? Thanks, AndreiQuestions: - Can and will this work for arrays of structs? - When doing manual GC allocations (for whatever reason), how can we later tell the GC what destructor to call? These questions combined are really aimed at Appender: I'm curious at if and how any changes will have to be made to it. Also question: Will this play nice wit exiting code that manually destroys GC allocated structs?
Aug 28 2014
On 8/29/2014 12:41 AM, monarch_dodra wrote:Questions: - Can and will this work for arrays of structs? - When doing manual GC allocations (for whatever reason), how can we later tell the GC what destructor to call?Yes, this does work for arrays of structs. Provided that you've passed in the type info for the struct when doing the manual allocation, it should call the destructor without anything extra needing to be done on the user's part.These questions combined are really aimed at Appender: I'm curious at if and how any changes will have to be made to it.Appender already uses the type info's destroy, so it shouldn't have any issues, as I already had to account for that.Also question: Will this play nice wit exiting code that manually destroys GC allocated structs?As I mentioned elsewhere, as long as the existing code is calling destroy, and not calling the finalizer directly, then yes, it will play nice, and only call the finalizer once.
Aug 29 2014
On Friday, 29 August 2014 at 18:12:04 UTC, Orvid King wrote:On 8/29/2014 12:41 AM, monarch_dodra wrote:Hum... by "manual" memory allocation. I meant this: GC.qalloc(newlen * T.sizeof, blockAttribute!T); That's what Appender does. Unless I'm mistaken, the Type info is not passed here? Furthermore, the Type info *can't* be passed...?Questions: - Can and will this work for arrays of structs? - When doing manual GC allocations (for whatever reason), how can we later tell the GC what destructor to call?Yes, this does work for arrays of structs. Provided that you've passed in the type info for the struct when doing the manual allocation, it should call the destructor without anything extra needing to be done on the user's part.This is news to me. Appender does not destroy anything. It makes no call to delete/destroy/release or whatnot. It simply just keeps allocating away.These questions combined are really aimed at Appender: I'mcurious at ifand how any changes will have to be made to it.Appender already uses the type info's destroy, so it shouldn't have any issues, as I already had to account for that.OK. Nice. Thanks. BTW: If Appender is "broken", that's OK (in the sense that it won't be any more "broken" than before). I just want as much information as possible about what I (we) will need to do to update it. In particular, Appender has an optimization that skips postblit to "relocate" when possible. If destructions start happening, then we'll need to make sure we first reset to "T.init", or we'll risk destroying a non-postblitted copy (which could be catastrophic in the case of RC'ed structs).Also question: Will this play nice wit exiting code thatmanuallydestroys GC allocated structs?As I mentioned elsewhere, as long as the existing code is calling destroy, and not calling the finalizer directly, then yes, it will play nice, and only call the finalizer once.
Aug 29 2014
On Friday, 29 August 2014 at 18:12:04 UTC, Orvid King wrote:On 8/29/2014 12:41 AM, monarch_dodra wrote:Hum... by "manual" memory allocation. I meant this: GC.qalloc(newlen * T.sizeof, blockAttribute!T); That's what Appender does. Unless I'm mistaken, the Type info is not passed here? Furthermore, the Type info *can't* be passed...?Questions: - Can and will this work for arrays of structs? - When doing manual GC allocations (for whatever reason), how can we later tell the GC what destructor to call?Yes, this does work for arrays of structs. Provided that you've passed in the type info for the struct when doing the manual allocation, it should call the destructor without anything extra needing to be done on the user's part.This is news to me. Appender does not destroy anything. It makes no call to delete/destroy/release or whatnot. It simply just keeps allocating away.These questions combined are really aimed at Appender: I'mcurious at ifand how any changes will have to be made to it.Appender already uses the type info's destroy, so it shouldn't have any issues, as I already had to account for that.OK. Nice. Thanks. BTW: If Appender is "broken", that's OK (in the sense that it won't be any more "broken" than before). I just want as much information as possible about what I (we) will need to do to update it. In particular, Appender has an optimization that skips postblit to "relocate" when possible. If destructions start happening, then we'll need to make sure we first reset to "T.init", or we'll risk destroying a non-postblitted copy (which could be catastrophic in the case of RC'ed structs).Also question: Will this play nice wit exiting code thatmanuallydestroys GC allocated structs?As I mentioned elsewhere, as long as the existing code is calling destroy, and not calling the finalizer directly, then yes, it will play nice, and only call the finalizer once.
Aug 29 2014
On 29/08/14 04:21, Andrei Alexandrescu wrote:Dear community, are you ready for this? https://issues.dlang.org/show_bug.cgi?id=2834 https://github.com/D-Programming-Language/druntime/pull/864Does this has the same issues as destructors for classes, i.e. not guaranteed to run? -- /Jacob Carlborg
Aug 28 2014
On Thu, 28 Aug 2014 19:21:04 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:Dear community, are you ready for this?yes, yes and yes!
Aug 28 2014
On 8/28/14, 11:13 PM, ketmar via Digitalmars-d wrote:On Thu, 28 Aug 2014 19:21:04 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:You forgot the Oxford comma :o). -- AndreiDear community, are you ready for this?yes, yes and yes!
Aug 29 2014
On Fri, 29 Aug 2014 09:49:07 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:yes, yes, and yes! fixed, ready to another round of reviews. ;-)yes, yes and yes!You forgot the Oxford comma :o). -- Andrei
Aug 29 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this?Yes! Whatever needs be done.
Aug 29 2014
On 8/29/14, ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Yeah destructors are a sore pain when they're unreliable. "May or may not be called" is just an awful semantic.Dear community, are you ready for this?Yes! Whatever needs be done.
Aug 29 2014
On Friday, 29 August 2014 at 09:08:07 UTC, Andrej Mitrovic via Digitalmars-d wrote:On 8/29/14, ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:That won't really change though, will it? AFAIK, it'll become: "will eventually be called at some unspecified point it time. The program may terminate before that happens, at which point, the destructor will never be called." ...right?On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Yeah destructors are a sore pain when they're unreliable. "May or may not be called" is just an awful semantic.Dear community, are you ready for this?Yes! Whatever needs be done.
Aug 29 2014
On Friday, 29 August 2014 at 09:16:36 UTC, monarch_dodra wrote:On Friday, 29 August 2014 at 09:08:07 UTC, Andrej Mitrovic via Digitalmars-d wrote:Yes, there's no way around this with a conservative GC.On 8/29/14, ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:That won't really change though, will it? AFAIK, it'll become: "will eventually be called at some unspecified point it time. The program may terminate before that happens, at which point, the destructor will never be called." ...right?On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Yeah destructors are a sore pain when they're unreliable. "May or may not be called" is just an awful semantic.Dear community, are you ready for this?Yes! Whatever needs be done.
Aug 29 2014
On 8/29/14, 2:16 AM, monarch_dodra wrote:On Friday, 29 August 2014 at 09:08:07 UTC, Andrej Mitrovic via Digitalmars-d wrote:Right, and reasonable. -- AndreiOn 8/29/14, ponce via Digitalmars-d <digitalmars-d puremagic.com> wrote:That won't really change though, will it? AFAIK, it'll become: "will eventually be called at some unspecified point it time. The program may terminate before that happens, at which point, the destructor will never be called." ....right?On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Yeah destructors are a sore pain when they're unreliable. "May or may not be called" is just an awful semantic.Dear community, are you ready for this?Yes! Whatever needs be done.
Aug 29 2014
On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Dear community, are you ready for this?Yes.This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it?I don't think so, it will just hinder adoption. If people don't want it they can stay with 2.066.
Aug 29 2014
On Friday, 29 August 2014 at 14:24:34 UTC, Peter Alexander wrote:On Friday, 29 August 2014 at 02:21:07 UTC, Andrei Alexandrescu wrote:Especially seeing as now we are doing patch releases.Dear community, are you ready for this?Yes.This is a significant change of behavior. Should we provide a temporary flag or attribute to disable it?I don't think so, it will just hinder adoption. If people don't want it they can stay with 2.066.
Aug 29 2014