www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Safe to cast to immutable and return?

reply Timoses <timosesu gmail.com> writes:
Is this safe?

class A {}
immutable(A) getA()
{
     A a;
     // .. do stuff with a
     // not leaking a to any functions

     // is this safe????
     return cast(immutable A)a;
}

What if A is replaced with A[] or A[int]?
If it's not safe, what would be the proper way to return an 
immutable instance from a function which needs to make 
adjustments to the instance before returning it as immutable?
Jul 05 2018
next sibling parent reply vit <vit vit.vit> writes:
On Thursday, 5 July 2018 at 11:15:03 UTC, Timoses wrote:
 Is this safe?

 class A {}
 immutable(A) getA()
 {
     A a;
     // .. do stuff with a
     // not leaking a to any functions

     // is this safe????
     return cast(immutable A)a;
 }

 What if A is replaced with A[] or A[int]?
 If it's not safe, what would be the proper way to return an 
 immutable instance from a function which needs to make 
 adjustments to the instance before returning it as immutable?
Try pure functions: class A {} A getA()pure safe //pure whitout mutable parameters guarantees that function doesn't leak data. { A a; // .. do stuff with a // not leaking a to any functions // is this safe???? return a; } A getA2(A x)pure safe //pure with mutable param { A a; // .. do stuff with a // not leaking a to any functions // is this safe???? return a; } void test() safe{ immutable(A) a1 = getA(); //ok immutable(A) a2 = getA2(null); //ok immutable(A) a3 = getA2(new A); //ok immutable(A) a4 = getA2(a3); //error in theory can leak }
Jul 05 2018
parent Timoses <timosesu gmail.com> writes:
On Thursday, 5 July 2018 at 12:15:35 UTC, vit wrote:
 Try pure functions:

 class A {}
 A getA()pure  safe  //pure whitout mutable parameters 
 guarantees that function doesn't leak data.
 {
      A a;
      // .. do stuff with a
      // not leaking a to any functions

      // is this safe????
      return a;
 }
 A getA2(A x)pure  safe  //pure with mutable param
 {
      A a;
      // .. do stuff with a
      // not leaking a to any functions

      // is this safe????
      return a;
 }

 void test() safe{
     immutable(A) a1 = getA();        //ok
     immutable(A) a2 = getA2(null);   //ok
     immutable(A) a3 = getA2(new A);  //ok
     immutable(A) a4 = getA2(a3);    //error in theory can leak
 }
Very nice! I assume the safe is not a must? Good read: https://dlang.org/spec/function.html#pure-functions
Jul 05 2018
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/5/18 7:15 AM, Timoses wrote:
 Is this safe?
 
 class A {}
 immutable(A) getA()
 {
      A a;
      // .. do stuff with a
      // not leaking a to any functions
 
      // is this safe????
      return cast(immutable A)a;
 }
As in safe? no. But it's safe in the fact that you aren't escaping any mutable references as immutable. However, casting is dangerous. It disables any checks about const safety that the compiler may do. If something happens to A where it all of a sudden gains a mutable reference, and the reference is to global data or has other references: class A { int *x; } int globalx; immutable(A) getA() { A a = new A; a.x = &globalx; return cast(immutable A)a; } Now it's not safe, and the compiler won't tell you.
 
 What if A is replaced with A[] or A[int]?
A[] should work very similarly to A A[int] I think will work, I don't think it stores any type info inside the AA. The rule is that if you *know* there are no other references to a mutable piece of data, it's OK to cast to immutable.
 If it's not safe, what would be the proper way to return an immutable 
 instance from a function which needs to make adjustments to the instance 
 before returning it as immutable?
See vit's response, he covers it pretty well. -Steve
Jul 05 2018