www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Inout table

reply nkm1 <t4nk074 openmailbox.org> writes:
There is this little table in 
https://dlang.org/spec/function.html#inout-functions:

Common qualifier of the two type qualifiers
                    mutable const  immutable inout inout const
mutable (= m)      m       c      c         c     c
const (= c)        c       c      c         c     c
immutable (= i)    c       c      i         wc    wc
inout (= w)        c       c      wc        w     wc
inout const (= wc) c       c      wc        wc    wc

I don't understand what it is trying to say. What is it that is 
calculated here? The qualifier for the return value?
And what's an "inout const"?
Sep 08
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/8/17 10:00 PM, nkm1 wrote:
 There is this little table in 
 https://dlang.org/spec/function.html#inout-functions:
 
 Common qualifier of the two type qualifiers
                     mutable const  immutable inout inout
const
 mutable (= m)      m       c      c         c     c
 const (= c)        c       c      c        
c     c
 immutable (= i)    c       c      i         wc    wc
 inout (= w)        c       c      wc        w    
wc
 inout const (= wc) c       c      wc        wc    wc
 
 I don't understand what it is trying to say. What is it that is 
 calculated here? The qualifier for the return value?
Correct. So given a function: inout(int*) foo(inout(int*)p1, inout(int*)p2) The table shows what inout is resolved as when calling the function. If you consider the column the mutability of p1, and the row the mutability of p2, then the value in the table represents the mutability of the return value. So for instance: int *m; const int *c; immutable int *i; inout int *w; auto v1 = foo(m, m); // typeof(v1) is int* auto v2 = foo(m, c); // typeof(v2) is const(int*) auto v3 = foo(i, m); // typeof(v3) is const(int*) auto v4 = foo(w, w); // typeof(v4) is inout(int*) auto v5 = foo(w, i); // typeof(v5) is inout(const(int *)) etc.
 And what's an "inout const"?
inout(const(T)) resolves to either immutable or const, depending on what inout ultimately resolves to. In other words, if inout is: mutable -> /*mutable*/(const(T)) // note no keyword for mutable, so it's just const(T) const -> const(const(T)) -> const(T) immutable -> immutable(const(T)) -> immutable(T) It was discovered that this extra mechanism has benefits (namely you can combine immutable data with inout data), so it now has it's own special place while using inout. A use case might be returning a sentinel value from a function: class Foo {} immutable sentinel = new Foo; inout(const(Foo)) foo(inout(Foo) f) { return someCond? sentinel : f; } Whenever an immutable Foo is passed in as f, then the result will be immutable. Otherwise, it's const. -Steve
Sep 13
parent reply nkm1 <t4nk074 openmailbox.org> writes:
On Wednesday, 13 September 2017 at 17:39:29 UTC, Steven 
Schveighoffer wrote:
 Correct. So given a function:

 inout(int*) foo(inout(int*)p1, inout(int*)p2)

 The table shows what inout is resolved as when calling the 
 function.

 If you consider the column the mutability of p1, and the row 
 the mutability of p2, then the value in the table represents 
 the mutability of the return value.

 So for instance:

 int *m;
 const int *c;
 immutable int *i;
 inout int *w;

 auto v1 = foo(m, m); // typeof(v1) is int*
 auto v2 = foo(m, c); // typeof(v2) is const(int*)
 auto v3 = foo(i, m); // typeof(v3) is const(int*)
 auto v4 = foo(w, w); // typeof(v4) is inout(int*)
 auto v5 = foo(w, i); // typeof(v5) is inout(const(int *))

 etc.
Thank you. Now it is clear to me. The source of my confusion was that, say, given a function: inout(int*) foo(inout(int*) p) as per table, combining (mutable) argument int* m with parameter inout(int*) p would produce parameter type const(int*). But now I see that the table deduces the common type of all parameters, not the common type of a parameter and its argument (the documentation is kind of hard to parse: "If such a match occurs, the inout is considered the common qualifier of the matched qualifiers...").
Sep 13
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/13/17 3:04 PM, nkm1 wrote:

 Thank you. Now it is clear to me. The source of my confusion was that, 
 say, given a function:
 inout(int*) foo(inout(int*) p)
 as per table, combining (mutable) argument int* m with parameter 
 inout(int*) p would produce parameter type const(int*). But now I see 
 that the table deduces the common type of all parameters, not the common 
 type of a parameter and its argument (the documentation is kind of hard 
 to parse: "If such a match occurs, the inout is considered the common 
 qualifier of the matched qualifiers...").
Yeah, I should update that table and inout explanation... -Steve
Sep 13