hasElaborateCopyConstructor bug?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Jun 2 19:36:25 UTC 2019


On Sunday, June 2, 2019 1:29:22 PM MDT Jonathan M Davis via Digitalmars-d-
learn wrote:
> On Sunday, June 2, 2019 8:32:16 AM MDT Paul Backus via Digitalmars-d-learn
> wrote:
> > On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote:
> > > Almost certainly, hasElaborateCopyConstructor should be updated
> > > to test for both postblit constructors and copy constructors,
> > > since its purpose is to test for whether the type has a
> > > user-defined copying function [...] Whether
> > > hasElaborateCopyConstructor was the best name is debatable, but
> > > it _does_ involve "elaborate" copying, and copy constructors
> > > weren't actually in the language at the time. The documentation
> > > is wonderfully confusing though in that it talks about copy
> > > constructors and then says that a copy constructor is
> > > introduced by defining this(this) for a struct. So, it
> > > basically calls a postblit constructor a copy constructor.
> >
> > I've made the mistake in the past of trying to use
> > hasElaborateCopyConstructor to test for the presence of
> > __xpostblit, and I'm sure I'm not the only one. The name is quite
> > misleading--even more so now that D has real copy constructors.
> >
> > If std.v2 ever materializes, we'll have an opportunity to fix
> > papercuts like this. Until then, my preferred workaround is to
> > use a renaming import:
> >
> > import std.traits: hasNontrivialCopy =
> > hasElaborateCopyConstructor;
>
> Why is it a mistake to use hasElaborateCopyConstructor to test for
> __xpostblit? Because you're trying to test for __xpostblit for some
> purpose other than determining whether the type is blittable? I'm not
> sure what other reason there would be to test for __xpostblit though.
> Either way, hasElaborateCopyConstructor currently checks for exactly that
> (with the addition that it checks whether a static array has elements
> with __xpostblit):
>
> template hasElaborateCopyConstructor(S)
> {
>     static if (__traits(isStaticArray, S) && S.length)
>     {
>         enum bool hasElaborateCopyConstructor =
> hasElaborateCopyConstructor! (typeof(S.init[0]));
>     }
>     else static if (is(S == struct))
>     {
>         enum hasElaborateCopyConstructor = __traits(hasMember, S,
> "__xpostblit");
>     }
>     else
>     {
>         enum bool hasElaborateCopyConstructor = false;
>     }
> }
>
> My point was that given the purpose of hasElaborateCopyConstructor,
> updating it to test for both a postblit constructor and copy constructor
> would be appropriate. In fact, the fact that it hasn't been means that
> the introduction of copy constructors has broken existing code (or at
> least that such code won't interact correctly with structs that have copy
> constructors). There should be no need to rename the trait, just update
> it, and whether it uses the name "elaborate" or "non-trivial" is pretty
> much irrelevant. Personally, I probably would have chosen hasNonTrivial
> over hasElaborate, but they mean the same thing, and we have
> hasElaborateDestructor for the corresponding test for destructors and
> hasElaborateAssign for the corresponding test for assignment. It really
> doesn't make sense to change the name at this point.

It looks like Manu already reported a bug on this:

https://issues.dlang.org/show_bug.cgi?id=19902

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list