www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - const objects

reply Dom DiSc <dominikus scherkl.de> writes:
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.

Is there a deeper reason why this is not allowed? Or is it simply 
not implemented?
Aug 17
parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
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.
Aug 17
parent Dom DiSc <dominikus scherkl.de> writes:
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!
Aug 17