Struct copy constructor with inout

Paul Backus snarwin at gmail.com
Tue Nov 14 13:49:21 UTC 2023


On Tuesday, 14 November 2023 at 08:50:34 UTC, dhs wrote:
> ```d
> struct S2
> {
>     this(ref inout S2 s) inout { writeln("copy"); }
>     int i;
> }
>
> void test()
> {
>     const(S1) s1;
>     S1 ss1 = s1; // error, ss1 not qualified as const
>
>     const(S2) s2;
>     S2 ss2 = s2; // fine, why?
> }
> ```
>
> Isn't "inout" supposed to copy the const-ness of its parameter 
> to the constructor's attribute? In other words: why doesn't 
> ss2=s2 fail here?

Because `S2` is a pure value type and contains no pointers or 
references, the compiler allows `const(S2)` to implicitly convert 
to `S2`. This is documented in the spec under ["Implicit 
Qualifier Conversions"][1], and you can verify it with a `static 
assert`:

```d
static assert(is(const(S2) : S2)); // ok
```

In order to prevent this conversion, you can replace `int i` with 
`int* p`:

```d
struct S3
{
     this(ref inout S2 s) inout { writeln("copy"); }
     int *p;
}

void test()
{
     const(S3) s3;
     S3 ss3 = s3;
     // Error: cannot implicitly convert expression
     // `s3` of type `const(S3)` to `S3`
}
```

[1]: 
https://dlang.org/spec/const3.html#implicit_qualifier_conversions


More information about the Digitalmars-d-learn mailing list