Inout table

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Sep 13 10:39:29 PDT 2017


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


More information about the Digitalmars-d-learn mailing list