digitalmars.D - copy-ctor's
- Manu (23/23) May 25 2019 So, it seems that if an object has a postblit and a copy constructor,
- Exil (7/32) May 25 2019 Seems a union also calls the postblit for every object in a
- Nicholas Wilson (8/21) May 25 2019 Correct, that is the transitional behaviour until postblit is
- Manu (12/25) May 26 2019 Right, but it's not a helpful behaviour; it undermines copy ctors...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/7) May 26 2019 It has, since 2010?
- Manu (3/10) May 26 2019 Haha, and I'm the OP... not surprised at all ;)
- Manu (3/17) May 26 2019 Oh, no.. that's search results, listed recent first. I didn't realise
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/8) May 26 2019 Oh yes, that can be confusing.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/17) May 26 2019 I vaguely remember Bearophile suggest that the union/struct
- Manu (10/29) May 26 2019 Well I'm obviously implementing a tagged union.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/13) May 26 2019 IIRC Bearophile suggested that the struct could provide a
- Manu (8/21) May 26 2019 Right, that's a terrible idea. Who's to say that's how the union is used...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/8) May 26 2019 Depends on how strict you want to be. In terms of correctness
- Manu (3/11) May 26 2019 Why? Then it would be impossible to use unions to write anything useful.
- RazvanN (17/42) May 27 2019 That's a bug, but I think that it's not going to be fixed since
- Manu (22/68) May 27 2019 How soon? Is this another case of "just wait 10 more years before you
- RazvanN (4/7) May 28 2019 Just for the record, I've made a PR that fixes this:
- Manu (4/11) May 28 2019 OMG so good!
So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred. It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred. I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid: struct S(T) { union { int x = 0; T y = void; } bool isT = false; } S a; S b = a; // calls `y's postblit, even though it's `isT` is false and the object is `void` initialised... So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here? Also, `hasElaborateCopyConstructor` is broken now. It should know about copy ctor's.
May 25 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred. It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred. I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid: struct S(T) { union { int x = 0; T y = void; } bool isT = false; } S a; S b = a; // calls `y's postblit, even though it's `isT` is false and the object is `void` initialised... So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here? Also, `hasElaborateCopyConstructor` is broken now. It should know about copy ctor's.Seems a union also calls the postblit for every object in a union, which makes less sense, since only one of them should be valid at a time. IIRC there was also a problem with copy constructors conflicting with the default constructor initalizers. Would probably be best to iron out all these bugs now before it gets used too much.
May 25 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred.Correct, that is the transitional behaviour until postblit is truly dead.It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred.Thats probably a bit of a grey area. I'll defer to Razvan for that one.I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:Thats a bug.So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?File a bug report and ensure that Razvan Nitu is CC'd.Also, `hasElaborateCopyConstructor` is broken now. It should know about copy ctor's.https://run.dlang.io/gist/71e722a80b5a9ab54625508915bc7738?compiler=dmd-beta _almost_ does it, I'm not quite sure what I'm missing though.
May 25 2019
On Sat, May 25, 2019 at 9:15 PM Nicholas Wilson via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:Right, but it's not a helpful behaviour; it undermines copy ctors... in my example above, 'S' can't control the template argument, which means `T` may have a postblit and so `S` can't possibly be written to work.So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred.Correct, that is the transitional behaviour until postblit is truly dead.Indeed. I also noticed another one; it doesn't just call postblit's for each item in the union, it also calls destructors for each item in the union! O_O How has this issue never come up?I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:Thats a bug.I don't know his email address... that CC box seems to work by email addresses.So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?File a bug report and ensure that Razvan Nitu is CC'd.
May 26 2019
On Sunday, 26 May 2019 at 20:38:48 UTC, Manu wrote:item in the union, it also calls destructors for each item in the union! O_O How has this issue never come up?It has, since 2010? https://forum.dlang.org/search?q=union%20destructors
May 26 2019
Haha, and I'm the OP... not surprised at all ;) On Sun, May 26, 2019 at 2:40 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 26 May 2019 at 20:38:48 UTC, Manu wrote:item in the union, it also calls destructors for each item in the union! O_O How has this issue never come up?It has, since 2010? https://forum.dlang.org/search?q=union%20destructors
May 26 2019
Oh, no.. that's search results, listed recent first. I didn't realise the forum could do that. On Sun, May 26, 2019 at 3:32 PM Manu <turkeyman gmail.com> wrote:Haha, and I'm the OP... not surprised at all ;) On Sun, May 26, 2019 at 2:40 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 26 May 2019 at 20:38:48 UTC, Manu wrote:item in the union, it also calls destructors for each item in the union! O_O How has this issue never come up?It has, since 2010? https://forum.dlang.org/search?q=union%20destructors
May 26 2019
On Sunday, 26 May 2019 at 22:33:48 UTC, Manu wrote:Oh, no.. that's search results, listed recent first. I didn't realise the forum could do that.Oh yes, that can be confusing. Untagged unions doesn't really play well with destructors in any language. I think C++ requires that those destructors are ignored and that the union's destructor should do the cleanup. Seems like a thing that is easy to forget though…
May 26 2019
On Sunday, 26 May 2019 at 23:45:05 UTC, Ola Fosheim Grøstad wrote:On Sunday, 26 May 2019 at 22:33:48 UTC, Manu wrote:I vaguely remember Bearophile suggest that the union/struct should provide a means to identify which type the union was holding. One usually has a union in a struct that also contains a tag of some sort that signifies the type of the union… but I think this is outside the scope of D as a language. So perhaps one should not be allowed to have destructors in untagged unions and encourage the use of tagged unions…Oh, no.. that's search results, listed recent first. I didn't realise the forum could do that.Oh yes, that can be confusing. Untagged unions doesn't really play well with destructors in any language. I think C++ requires that those destructors are ignored and that the union's destructor should do the cleanup. Seems like a thing that is easy to forget though…
May 26 2019
On Sun, May 26, 2019 at 4:55 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Sunday, 26 May 2019 at 23:45:05 UTC, Ola Fosheim Grøstad wrote:Well I'm obviously implementing a tagged union. The language just needs to make the feature available, and let me wrap it up. The proper thing to do here, is disable field-copy/destruction for items in unions, and if the owning type doesn't declare copy-ctor/destructors, then the default functions should be disabled rather than generated from fields as usual. It should also be un- safe to reference a member of a union from any method, and from there we have everything we need to write tooling.On Sunday, 26 May 2019 at 22:33:48 UTC, Manu wrote:I vaguely remember Bearophile suggest that the union/struct should provide a means to identify which type the union was holding. One usually has a union in a struct that also contains a tag of some sort that signifies the type of the union… but I think this is outside the scope of D as a language. So perhaps one should not be allowed to have destructors in untagged unions and encourage the use of tagged unions…Oh, no.. that's search results, listed recent first. I didn't realise the forum could do that.Oh yes, that can be confusing. Untagged unions doesn't really play well with destructors in any language. I think C++ requires that those destructors are ignored and that the union's destructor should do the cleanup. Seems like a thing that is easy to forget though…
May 26 2019
On Monday, 27 May 2019 at 00:41:22 UTC, Manu wrote:Well I'm obviously implementing a tagged union. The language just needs to make the feature available, and let me wrap it up.IIRC Bearophile suggested that the struct could provide a function or some mechanism that would tell the runtime what type the union contained. But Andrei didn't like it. Some sort of "type-switch" statement in the union with a conditional that is allowed to reference fields in the surrounding struct would be a possibility. The real problem isn't that one cannot come up with a decent solution, but that the semantics of C has been subsumed, and extended.
May 26 2019
On Sun, May 26, 2019 at 7:55 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 27 May 2019 at 00:41:22 UTC, Manu wrote:Right, that's a terrible idea. Who's to say that's how the union is used.Well I'm obviously implementing a tagged union. The language just needs to make the feature available, and let me wrap it up.IIRC Bearophile suggested that the struct could provide a function or some mechanism that would tell the runtime what type the union contained. But Andrei didn't like it.Some sort of "type-switch" statement in the union with a conditional that is allowed to reference fields in the surrounding struct would be a possibility.Sounds like a lib to me.The real problem isn't that one cannot come up with a decent solution, but that the semantics of C has been subsumed, and extended.I don't really think there's a problem here, just disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un- safe. The rest will fall out naturally.
May 26 2019
On Monday, 27 May 2019 at 04:52:14 UTC, Manu wrote:I don't really think there's a problem here, just disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un- safe. The rest will fall out naturally.Depends on how strict you want to be. In terms of correctness you shouldn't allow anything with a destructor in a union in the first place.
May 26 2019
On Sun, May 26, 2019 at 10:20 PM Ola Fosheim Grøstad via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Monday, 27 May 2019 at 04:52:14 UTC, Manu wrote:Why? Then it would be impossible to use unions to write anything useful.I don't really think there's a problem here, just disable the default copy/postblit/destructor in the presence of a union, and also make any access to a member of a union un- safe. The rest will fall out naturally.Depends on how strict you want to be. In terms of correctness you shouldn't allow anything with a destructor in a union in the first place.
May 26 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred. It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred. I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:That's a bug, but I think that it's not going to be fixed since the postblit should be deprecated soon.struct S(T) { union { int x = 0; T y = void; } bool isT = false; } S a; S b = a; // calls `y's postblit, even though it's `isT` is false and the object is `void` initialised... So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?Currently, you don't have any options. As I see it, there are 3 possible solutions: 1. Change the semantics of `disable this(this)` from "object is not copyable" to "object is not copyable through postblit". This way we can exclude postblits but allow copies using the copy constructor. 2. Check if T has postblit with a static if (via traits) and define the copy constructor only if T does not have a postblit. 3. Issue a deprecation if T has a postblit. Essentially, there is no clear way in how you can mix object with postblits and objects with copy constructorAlso, `hasElaborateCopyConstructor` is broken now. It should know about copy ctor's.
May 27 2019
On Mon, May 27, 2019 at 2:11 AM RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:How soon? Is this another case of "just wait 10 more years before you can use D"? It looks like it needed to be fixed about 10 years ago, so no time like the present! :)So, it seems that if an object has a postblit and a copy constructor, the postblit is preferred. It also seems that if an object has a copy constructor and a MEMBER with a postblit, then object has a postblit generated which calls through to the member, and that is preferred. I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:That's a bug, but I think that it's not going to be fixed since the postblit should be deprecated soon.Good idea, and easy to implement in minutes! It's not a solution though, but it is one piece in a larger puzzle.struct S(T) { union { int x = 0; T y = void; } bool isT = false; } S a; S b = a; // calls `y's postblit, even though it's `isT` is false and the object is `void` initialised... So, it's very hard to craft a tool like 'S', when the supplied T might have a postblit and ruin everything. What are my options here?Currently, you don't have any options. As I see it, there are 3 possible solutions: 1. Change the semantics of `disable this(this)` from "object is not copyable" to "object is not copyable through postblit". This way we can exclude postblits but allow copies using the copy constructor.2. Check if T has postblit with a static if (via traits) and define the copy constructor only if T does not have a postblit.This is useless, because if S does not have a copy constructor, the object can't work under any circumstances. It also wouldn't solve the problem, since the union item's destructor is still called by the same rules, so copying is not the only issue here.3. Issue a deprecation if T has a postblit. Essentially, there is no clear way in how you can mix object with postblits and objects with copy constructorRight, they shouldn't be mixed. In this case, I could move forwards if the union issue was fixed though. If T in the union did NOT call field-copy and field-destruction (which is just a bug!), then I could static-check and manually handle the 2 cases of whether T has a copyctor or a postblit in the implementation of the copy ctor of S, so I could reconcile the difference with some extra work in S. I think the only path to solution is to fix the issue with unions, and that absolutely needs to happen anyway regardless.
May 27 2019
On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:Just for the record, I've made a PR that fixes this: https://github.com/dlang/dmd/pull/9909 Hope this will be of help for you, Manu.
May 28 2019
On Tue, May 28, 2019 at 6:30 AM RazvanN via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Saturday, 25 May 2019 at 23:15:05 UTC, Manu wrote:OMG so good! Bonus points if any access to members of a union is un- safe...I have also noticed that if you have a union containing an item with a postblit, the postblit is always called, even if the item in the union is not valid:Just for the record, I've made a PR that fixes this: https://github.com/dlang/dmd/pull/9909 Hope this will be of help for you, Manu.
May 28 2019