DIP 1018--The Copy Constructor--Community Review Round 1

RazvanN razvan.nitu1305 at gmail.com
Sat Jan 5 13:34:09 UTC 2019


On Friday, 21 December 2018 at 14:43:50 UTC, Boris-Barboris wrote:
> On Tuesday, 18 December 2018 at 14:51:39 UTC, Mike Parker wrote:
>> This is the feedback thread for the first round of Community 
>> Review for DIP 1018, "The Copy Constructor"
>
> 1). I do not like the ability to specify a mutable copy source. 
> Under no circumstance should the code like
>
> A a;
> A fun()
> {
>     return a;      // lowered to return tmp.copyCtor(a)
> }
>
> void main()
> {
>     A b = fun();    // the return value of fun() is moved to 
> the location of b
> }
>
> be allowed to modify the value of a. This is an absolute pain 
> to read\debug, and I would instead like to see a mandatory 
> const\immutable on the source reference.
> Copy operation should not modify the source, or it should not 
> be called a copy. If we are talking about a typical smart 
> pointer struct (Refcounted), copy still should not modify the 
> source. It is D's transitive const\immutable that is a problem 
> here and it must be explicitly casted away by the developer.
>
> Only const also mitigates the combinatorial mess caused by 4 
> combinations of mutable\immutable copy constructors, since 
> immutable is implicitly converted to const.

As it was stated above, the transitive nature of const and 
immutable
makes it impossible to safely copy objects with indirections. If 
you do
not want to modify the source, then don't modify it from the copy 
constructor.
This can be seen as a feature, not a bug.

> 2). "A declaration is a copy constructor declaration if it is a 
> constructor declaration that takes only one non-default 
> parameter by reference that is of the same type as 
> typeof(this), followed by any number of default parameters..."
>
> If you need other parameters, you are not performing a copy. 
> Copy constructor needs no additional parameters. If the 
> semantics of your domain problem involve parametrized post-copy 
> operations, the code should state that explicitly - by using 
> specialized properly-named methods, that notify the reader 
> about this particularity.
>
>
Agree, that was my initial design too, but in C++ you can define 
any number of
default parameters and people coming from that background might 
have some cases
where it is useful for them to have default parameters. Since 
this is the first
iteration of a copy constructor implementation, we should try to 
stick as much
as possible to the C++ design. Of course, in the case of const 
source we cannot
do that since const means something else in D.

> 3). Section "Copy constructor usage", I don't understand the 
> difference:
>
> void main()
> {
>     A a;
>     A b = a; // copy constructor gets called
>     b = a;   // assignment, not initialization
> }
>
A b = a is an initialization, therefore the copy constructor gets 
called.
b = a is an assignemnt => opAssign gets called

> and
>
> void main()
> {
>     A a;
>     a = fun();      // NRVO - no copy constructor call
fun() returns by value so a copy constructor call should be 
performed when returning, but in this case, because named return 
value optimization may be
applied, it will elide the copy.

>     A b; // b is initialized after this semicolon.
>     // why is this one not an assignment, but initialization?
>     // do we have the difference formally and consistently 
> defined for structs?
>     b = gun();      // NRVO cannot be performed, copy 
> constructor is called
> }

Indeed, these examples are a bit confusing, because the copy 
constructor is called when returning, not on caller site. Even if 
you would have `A b = gun()`, the value of gun() would be moved, 
but a copy constructor may be called when returning from gun.



More information about the Digitalmars-d mailing list