## digitalmars.D.learn - Inout table

• nkm1 (12/12) Sep 08 2017 There is this little table in
• Steven Schveighoffer (35/49) Sep 13 2017 Correct. So given a function:
• nkm1 (12/30) Sep 13 2017 Thank you. Now it is clear to me. The source of my confusion was
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 2017
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 2017
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 2017
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 2017