relax inout rules?

Timon Gehr timon.gehr at gmx.ch
Tue Dec 13 02:21:24 PST 2011


On 12/13/2011 09:41 AM, kenji hara wrote:
> 2011/12/13 Steven Schveighoffer<schveiguy at yahoo.com>:
>> Currently, the rules of inout say you cannot put inout on a parameter
>> without putting it on the return type as well.  This makes sense, it gives
>> the compiler one place to worry about whether implicit casting rules will
>> properly work.
>>
>> But Timon Gehr brought up in another thread (started by Merdhad) that we can
>> separate the resolution of inout from the applicability of the parameters.
>>   Essentially, calling an inout function goes through two phases:
>>
>> 1. determine what inout resolves to
>> 2. try and call the function.
>>
>> inout rules don't have to change regarding resolving inout's actual value.
>>   In other words, if all inout places are matched as int, immutable, or
>> inout, then inout resolves to that value.  Otherwise inout resolves to
>> const.
>>
>> But what's different is (at least in my mind) the function call might not
>> necessarily succeed even when the resolution is completed.
>>
>> Take for example:
>>
>> inout(int)* foo(inout(int)** a, inout(int)* b);
>>
>> Now, if we call foo like this:
>>
>> int a;
>> int b;
>> int* pa =&a;
>>
>> foo(&pa,&b);
>>
>> This means foo is called with (int **, int *).  This means inout resolves to
>> mutable (no qualifier).  *NOW* we try calling foo as if it were written:
>>
>> int *foo(int **a, int *b)
>>
>> And it can be done.  Not only that, but there is nothing bad that could be
>> happening in foo that should be disallowed by the compiler.
>>
>> Now let's see what happens were we *could* do something bad:
>>
>> immutable(int) c;
>> auto pc =&c;
>>
>> foo(&pc,&b);
>>
>> Now, foo is being called with (immutable(int)**, int *).  Inout resolves to
>> const (due to the mix of mutable and immutable).  *NOW* we try calling foo
>> as if it were written:
>>
>> const(int)* foo(const(int)** a, const(int)* b);
>>
>> And it *FAILS*.  This is because you cannot implicitly convert
>> immutable(int)** to const(int)** (well, at least it *shouldn't* compile, I'm
>> not sure if it does currently).
>
> Separating phases is good.
> Current implementation does not separate the two phases, and I agree
> that has a bug you appears.
>
> And, we need fixing issue 4251 and 5493 to fill the hole of const system.
> Today, I've posted a pull for it.
> https://github.com/D-Programming-Language/dmd/pull/558
>
>> What this does is allow more possibilities for inout than we currently do.
>>   Because inout is not now tied to returning something, we can create
>> functions that have inout parameters but no inout return value.
>>
>> The example we were discussing on the other thread was this:
>>
>> void foo(ref inout(int)* a, inout(int)* b) { a = b;}
>>
>> This would compile as long as you call with const(int)* as the first
>> parameter, or if both parameters matched in constancy (i.e. both were
>> immutable, both were mutable, or both were inout).
>>
>> This gives us more cases where you don't have to repeat functions for the
>> sake of handling different types of constancy, particularly when we have
>> mutable references 2 levels deep.  I can't see anything technically wrong
>> with this, can anyone else?
>>
>> The one thing that I think still should be required is if you have inout on
>> the return value, there *must* be an inout on a parameter.  Otherwise, the
>> compiler has no idea what it should be (since we don't overload on return
>> type in D).
>>
>> If this ends up being viable, this is actually easier to explain than the
>> current rules for inout.  We just have to make sure the rules are sound
>> before doing something like this.
>>
>> -Steve
>
> Against an inout function that does not return inout type:
> - the number of inout parameters should be 2 more?

If we required that, then IFTI would also have to replace inout with 
const in case there is only one of them. That potentially introduces 
counter-intuitive behaviour.

> - at least one parameter should have 'out' or 'ref' storage class as a
> *return parameter*?

Not necessarily.

>
> But I'm not sure these restrictions are necessarily required.
>
> Kenji Hara

I think we should indeed drop the restrictions, because they complicate 
the language for little gain.




More information about the Digitalmars-d mailing list