Copy constructors #9494
Replies: 5 comments 2 replies
-
Wouldn't this be a breaking change for structs that already have a ctor of that shape? |
Beta Was this translation helpful? Give feedback.
-
I haven't thought about this in depth, but is this enough? Do we also need move semantic/borrow check etc. to make this safe? |
Beta Was this translation helpful? Give feedback.
-
This also falls apart with generics, or anywhere a struct would be assigned outside of the language's control. |
Beta Was this translation helpful? Give feedback.
-
I wouldn't call this a severe issue. It's not blocking at all either. You get the same issue with all mutable structs or structs that can mutate their indirect contents. That is, you get the same "issue" with For existing structs, like |
Beta Was this translation helpful? Give feedback.
-
It feels like implementation of the operator should account for the fact that array could be used elsewhere, and not be as simple as |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Motivation
While experimenting with compound assignment operators in C# 14, I found a severe problem that with structs it's impossible to properly implement in-place updates for structs because of the copy semantic coming with structs.
Taking the following code as an example,
Here
foo
is copied tobar
, and the following+=
is operated onfoo
. Butfoo
andbar
shares the same_array
so that you cannot properly implement in-place updates forFoo
.BigInteger
will suffer from exactly the same problem.Copy constructors
Here I propose to introduce copy constructors. A copy constructor is a constructor that takes a ref (or a readonly ref) of the containing type. For example:
When the compiler sees any assignment from the same type, it emits a call to the copy constructor if there's one, so that
var bar = foo
becomesvar bar = new Foo(in foo)
.And when the compiler sees a struct implementing a compound assignment operator, it should warn the user to implement a copy constructor if there isn't any.
The implementation of
Foo
will be:But with this approach we may need runtime support to achieve proper behavior for generics, for example:
Alternatives
An alternative is to allow overloading assignment operator
=
.Now we can finally implement in-place updates for structs properly:
And when the compiler sees a struct overloading a compound assignment operator, it should warn the user to overload the assignment operator.
In generic context, the compiler should emit
operator=
if the generic type has an available implementation ofoperator=
in the generic constraints:However, this won't be sufficient to resolve all the issues, for example:
So ultimately, we would still need copy constructors.
cc: @AlekseyTs
Beta Was this translation helpful? Give feedback.
All reactions