hasElaborateCopyConstructor bug?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Jun 2 06:59:02 UTC 2019


On Saturday, June 1, 2019 5:29:08 PM MDT SrMordred via Digitalmars-d-learn 
wrote:
> On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote:
> > On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote:
> >
> > hasElaborateCopyConstructor checks if the type defines a
> > postblit[0].
>
>   Yes, I know this.
>
> But since dmd 2.086 we have copy ctors:
> https://dlang.org/changelog/2.086.0.html#copy_constructor
>
> And its seem logical that if I want a trait that check if copy
> ctors exists I will use this name 'hasElaborateCopyConstructor'
>
> So it looks like a naming issue for me.
> Unless postblits will be eventually replaced by copy ctors.

Effectively, postblit constructors are being replaced by copy constructors.
Ideally, no new code would be written with postblit constructors, and all
existing postblit constructors would eventually be replaced with copy
constructors. However, because of how long postblit constructors have
existed in the language, Walter has no interest in actually deprecating them
until he actually has to (so potentially never) in order to avoid code
breakage.

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 (be it
explicitly or because the type contains a type with a user-defined copying
function) - and thus whether copying the type involves anything other than
simply blitting. Historically, the user-defined copying function has been
the postblit constructor, but whether it's a postblit constructor or a copy
constructor is pretty much irrelevant to the purpose of the trait.

It does make _some_ sense that it's not hasPostblit or
hasPostblitConstructor, because that could easily be misconstrued as being
whether it explicitly has a user-defined postblit constructor, which isn't
what it tests. If a type has a postblit constructor in it directly, it has
the member __postblit and the member __xpostblit (where __postblit is the
explicitly declared postblit constructor and __xpostblit is what calls the
postblit constructor). However, if the type does not directly declare a
postblit constructor but it has a member that does declare one (directly or
indirectly), then it will just have __xpostblit, which will in turn deal
with copying each member correctly. So, calling the trait hasPostblit could
easily have given the wrong impression. 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.

Regardless, as long as changing hasElaborateCopyConstructor to test for both
the postblit constructor and the copy constructor isn't likely to break
anything (and I don't _think_ that it will, but I'd have to think about it
more to say for sure), then it should just be updated to take copy
constructors into account. And if we ever do reach the point that we
actually fully get rid of postblit constructors, then
hasElaborateCopyConstructor can be updated to not test for postblit
constructors any longer.

- Jonathan M Davis






More information about the Digitalmars-d-learn mailing list