Thread overview
const objects
3 days ago
Dom DiSc
3 days ago
H. S. Teoh
3 days ago
Dom DiSc
3 days ago

If I do:

struct S1
{
   const int* my_x;
   this(const int* x) { my_x = x; }
}

struct S2
{
   int* my_x;
   this(int* x) { my_x = x; }
}

main()
{
   immutable int i = 5;
   S1 s = S1(&i); // works
   immutable S2 t = S2(&i); // fails
}

Shoudn't S2 also work? It's immutable, so even if it takes only a mutable parameter, it is ensured it will not change it, because it is itself immutable, so none of its attributes can be modified nor can non-const member functions be called.

Is there a deeper reason why this is not allowed? Or is it simply not implemented?

3 days ago
On Sun, Aug 17, 2025 at 01:21:34PM +0000, Dom DiSc via Digitalmars-d-learn wrote:
> If I do:
> ```d
> struct S1
> {
>    const int* my_x;
>    this(const int* x) { my_x = x; }
> }
> 
> struct S2
> {
>    int* my_x;
>    this(int* x) { my_x = x; }
> }
> 
> main()
> {
>    immutable int i = 5;
>    S1 s = S1(&i); // works
>    immutable S2 t = S2(&i); // fails
> }
> ```
> 
> Shoudn't S2 also work? It's immutable, so even if it takes only a mutable parameter, it is ensured it will not change it, because it is itself immutable, so none of its attributes can be modified nor can non-const member functions be called.
[...]

This is not allowed because S2.this explicitly takes a mutable pointer to mutable data (int*).  The compiler only checks the signature of S2.this, not its body, when checking the validity of this ctor call.

If you want to pass an immutable pointer to S2.this, you need to use `inout`:

```d
struct S2
{
    int* my_x;
    this(inout(int)* x) inout { my_x = x; }
}

void main(string[] args) {
	immutable int i = 1;
	auto s2 = immutable(S2)(&i); // OK
}
```


T

-- 
Food and laptops don't mix.
3 days ago
On Sunday, 17 August 2025 at 15:09:30 UTC, H. S. Teoh wrote:

> If you want to pass an immutable pointer to S2.this, you need to use `inout`:
>
> ```d
> struct S2
> {
>     int* my_x;
>     this(inout(int)* x) inout { my_x = x; }
> }
>
> void main(string[] args) {
> 	immutable int i = 1;
> 	auto s2 = immutable(S2)(&i); // OK
> }
> ```

Ah! I thought of inout, but it is not allowed on member variables. I didn't know that I can mark the constructor inout.

Many thanks, this works!