template ctor overload Segmentation fault
RazvanN
razvan.nitu1305 at gmail.com
Tue Dec 14 12:04:36 UTC 2021
On Sunday, 12 December 2021 at 11:57:43 UTC, vit wrote:
> Hello, why does this code fail to compile?
>
> ```d
> struct Foo(T){
> this(Rhs, this This)(scope Rhs rhs){
> }
>
> this(ref scope typeof(this) rhs){
> }
> }
>
>
> struct Bar{
> Foo!int foo;
> }
>
> void main(){
> }
> ```
>
> error: Segmentation fault (core dumped)
The problem is that the compiler will try to generate an inout
copy constructor for Bar that looks roughly like this:
```
this(ref scope inout(Bar) p) inout
{
this.foo = p;
}
```
The idea behind this lowering is to try and call the copy
constructor for Foo object if possible. One issue here is that
copy constructors have the same symbol name as constructors
(__ctor), so `this.foo = p` gets lowered to `foo.__ctor(p)`.
Since both the instance and the parameter are inout, the copy
constructor of Foo cannot be called, so the templated constructor
is called. After generating the template instance of the
constructor, you end up with `this(scope inout(Foo)) inout` ;
that is basically an rvalue constructor. This is not valid code;
if you write:
```
struct Foo(T){
//this(Rhs, this This)(scope Rhs rhs){}
this(scope inout(Foo!int) rhs) inout {}
this(ref scope typeof(this) rhs){
}
}
```
You will get an error stating that you cannot define both an
rvalue constructor and a copy constructor. However, since the
constructor is templated it is impossible for the compiler to
issue this error before actually instantiating the constructor. I
see 2 possible fixes for this: (1) either we rename the copy
constructor symbol to __cpCtor so that it does not clash with the
normal constructor overload set or (2) when a templated
constructor is instantiated, we can check whether it is an rvalue
constructor and issue an error if a copy constructor exists.
When I implemented the copy constructor I thought that it would
better to have the copy constructor on a different overload set
than the normal constructors, however, Walter insisted that they
have the same name. So, I guess (2) is the way to go.
Cheers,
RazvanN
More information about the Digitalmars-d-learn
mailing list