fix Issue 14246 - RAII - proper destruction of partially constructed …#8697
fix Issue 14246 - RAII - proper destruction of partially constructed …#8697WalterBright merged 1 commit intodlang:masterfrom
Conversation
|
Thanks for your pull request, @WalterBright! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#8697" |
ce2f721 to
4aa31a7
Compare
|
Copying from my comment from earlier:
If it is at all desired for this to eventually be the default behaviour then this needs to come with compiler generated unittests to verify the behaviour of destructors on non-constructed objects. This also doesn't fix the problem of destructors that throw in the |
|
This appears to have regressed issue 9386. |
0f52a7e to
4ddc68d
Compare
|
Issue 9386 is in sdtor.d, and is apparently passing. |
It's no different from any other case of throwing inside a scope(failure). I.e. it's not a special case. |
4ddc68d to
241eacb
Compare
|
So to clarify, if an field is left default-initialized, will the destructor get called for it? |
|
Yes. Thats what broke lots of code last time, and why it is behind a switch this time. This will therefore only break code on request to fix the already broken code :) |
|
For the record I don't think this is the correct way to fix 14246 (it may function as a stop gap for Weka in the interim though): Note that this only needs to be done for constructors that are |
Yes. |
Hence my suggestion that attributes on the ctor declaration should only apply to the user-defined body, not the dtor calls behind the scenes. |
That makes the attributes meaningless, though. It shouldn't be hard for people to fix their destructors, and with the switch they'll have plenty of time to do it. Most of the fixes will be simply adding the attribute. |
In D, a default initialized object is a valid object. To write code otherwise will be step-by-step fighting the language. |
It doesn't – they would still be checked at the call site (i.e. where the object is constructed). |
This is obvious and does not need repeating. In cases problematic w.r.t. backwards-compatibility, the issue is that from the user's perspective, none of their constructor code is actually struct Foo {
this() @safe @nogc pure { … }
static __ctor(ref Foo f) { // inferred attributes
scope (failure) f.__fieldDtor();
f.this();
}
…
}This is obviously pseudo-code – there wouldn't actually be two functions, etc. –, but should clarify what is meant. |
|
I understand your proposal. But the result is that the constructor's behavior will not conform to its attributes, and so will engender a critical bug report. I'm afraid I'd have to agree :-(
|
This is a result of a chain of consequences:
So the error message should be When using Note that this will not change the safeness or nogcness of since the destructor is called. Problems will arise when dynamically allocating a |
|
I have a reservation regarding this feature as implemented and |
|
Keep in mind that is also going to fail miserably. |
|
Having it So, assuming |
|
Some options:
Also, consider that the only point to |
241eacb to
20d2bc1
Compare
20d2bc1 to
a9ee4ce
Compare
|
I'm not sure I follow. Let's put in a concrete example: How do you suggest we avoid unnecessarily initializing 10 million elements of unknown size? |
|
|
||
| nothrow void notthrow() { } | ||
|
|
||
| class C66 |
There was a problem hiding this comment.
What is the purpose of this code? I don't see any instances of this class anywhere. Maybe it should be moved to the compilable directory?
There was a problem hiding this comment.
What is the purpose of this code?
To compile successfully.
Maybe it should be moved to the compilable directory?
Perhaps, but I wanted the struct destructor tests in one file.
|
@Shachar is the destructor for T, or for StaticArrayContainer? |
|
@WalterBright IT's for T. The idea is to have a container with a fixed maximal capacity, but which otherwise behaves like an array (with variable length). Setting length to longer produces elements initialized to init. Setting it to lower would destruct the existing elements. |
|
@Shachar One method is to type the array elements as |
| * https://issues.dlang.org/show_bug.cgi?id=14246 | ||
| */ | ||
| AggregateDeclaration ad = ctor.toParent2().isAggregateDeclaration(); | ||
| if (ad && ad.fieldDtor && global.params.dtorFields) |
There was a problem hiding this comment.
Is the check for ad really necessary? Isn't this already checked in semantic1 ?
There was a problem hiding this comment.
Sometimes, as a result of previous errors and error recovery, the AST isn't always in a completely consistent state. Expression nodes could be ErrorExp, Type nodes could be Terror, and even that isn't always done properly.
…objects/structs
This is a reboot of #6816 , but puts it behind the compiler switch
-transition=dtorfieldsso it will work with incorrect existing code.