Copy Constructor DIP

Manu turkeyman at gmail.com
Thu Jul 12 20:29:43 UTC 2018


On Wed, 11 Jul 2018 at 23:55, RazvanN via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> > What's wrong with:
> > struct S {
> >   this(ref S copyFrom);
> > }
> >
> > That looks like a perfectly good copy constructor declaration
> > ;) I'm just saying, the DIP needs to explain this.
>
> That is actually a valid constructor, according to today's
> compiler. There
> might be code out there that uses this syntax for the constructor
> and overnight
> it will be turned into a copy constructor.

Exactly. Is that a problem?
It probably IS a copy constructor already, what else could it be? :)

> I agree that the current syntax is lacking. This was Andrei's
> proposition
> and I was initially against it, but he said to put it in the DIP
> so that
> we can discuss it as a community. Maybe this syntax is better:
>
> @this(ref S a another)
>
> It looks like the c++ copy constructor but the `@` makes it
> different from
> a constructor, so we're good. What do you think?

I would struggle to get behind anything other than `this(ref T)`
1. There's an extremely low probability such a function exists in any
code, because it's redundant in the current language (postblit)
2. If it does exist, there's an extremely low probability that it's
not already a valid copy constructor (what else could it possibly
be?!)
3. The remaining cases are crazy.

extremely^^2 low probability of causing an issue is not worth
butchering the syntax for all time to come... if you ask me.
Can the DIP identify a couple of trouble cases and present as
motivation for the silly syntax? If no such cases can be identified,
then it's hard to support an argument in favour.

> > Right. This is all obvious and intuitive.
> > What I'm hearing is that under this proposal, copy constructors
> > and
> > assignment operators DO come in pairs (just like in C++), but
> > that's
> > not mentioned here in this DIP. Since this proposal will
> > introduce
> > that recommended pattern from C++, it may be worth mentioning.
>
> If by "come in pairs" you mean that you can define them both,
> then yes,
> that is the case. Will add a paragraph in the DIP to specify this.

Well, in C++ they SHOULD come in pairs. Things don't work if they
don't, and I expect the same truth will emerge here.
I'd like to see the DIP explore the parallel; understand why C++
specifies that they must come in pairs, and then explain that the same
reasons also apply to D, or why they don't.
Does dlang now have the 'rule-of-3' (or 5 now in c++11)?

> You mentioned that it's terrible that the assignment operator
> and the copy constructor come in pairs. Why is that? Would you
> rather
> have a copy constructor that is used also as an assignment
> operator?

It's pretty lame that C++ requires you to effectively write the same
function twice in 2 different ways. It might be nice to explore if
there's any way to unify them...
I often define C++ assignment operators like this to save on code duplication:
  T& operator=(const T& rh) { this->~T(); new(this) T(rh); }

I would hate to see this emerge as a pattern:
  void opAssign(ref T rh) { this.destroy(); emplace(&this, rh); }

Being able to implement them both independently is *occasionally*
useful, but 95% of the time, destruct + copy-construct is an equally
efficient implementation for assignment. I'd suggest that this
destruct+copy-construct pattern is a perfectly good substitute for
assignment in most cases, and maybe the compiler should deploy the
pattern as an implicit copy constructor in lieu of an explicit one?
So, if the user specifies a complex copy constructor, but no
assignment operator (which just blits on copy), then they've almost
certainly introduced a bug on copying! Perhaps the compiler should
automatically emit an assignment operator implemented as above in
presence of a (suite of? [const/immutable/etc permutations]) 'complex'
copy constructor?


More information about the Digitalmars-d mailing list