On 6/13/17 5:58 PM, ag0aep6g wrote:
On 06/13/2017 10:50 PM, Steven Schveighoffer wrote:
const(inout) actually *is* a thing :)

It's a type constructor that can be implicitly cast from immutable.
This has advantages in some cases.

See (horribly written) table at the bottom if the inout function
section here: http://dlang.org/spec/function.html#inout-functions

Also I talked about it last year at Dconf 2016:
http://dconf.org/2016/talks/schveighoffer.html

Huh. There it is.

Took me some experimenting to understand what it does. If anyone else is
interested, this is where it clicked for me:

----
inout(int*) f(inout int* x, inout int* y)
{
    return y;
}

inout(int*) g(inout int* x)
{
    immutable int* y;
    return f(x, y); /* Error: cannot implicitly convert expression f(x,
y) of type inout(const(int*)) to inout(int*) */
}
----

That code can't compile because g's inout return type says that it has
to return a mutable result for a mutable argument x. But y is immutable,
so that can't work.

We see in the error message that `f(x, y)` results in a `inout(const
int*)`. We can change g's return type to that (or `auto`) and the code
compiles. `inout const` enforces that the result is const or immutable.
It cannot be mutable.

This raises a question: There is no analogous inout variant that goes
the other way (to mutable and const but not immutable), is there?

No, the fact that immutable implicitly casts to const(inout) is a special property enabled by the knowledge that immutable data can NEVER change, so it's OK to assume it's (at least) const for all references. The same cannot be true of const or mutable.


This code doesn't work, and I see no way to make it work:

----
inout(int*) f(inout int* x, inout int* y)
{
    return y;
}

auto g(inout int* x)
{
    int* y;
    return f(x, y);
}

void main()
{
    int* x;
    int* r1 = g(x);
}
----

This cannot work, because g() has no idea what the true mutability of x is. inout is not a template. This is why you can't implicitly cast inout to anything except const, and you can't implicitly cast anything to inout.

So it MUST return const(int *) (if you did auto r1 = g(x), typeof(r1) would be const(int *)).

-Steve

Reply via email to