inout and function/delegate parameters

Steven Schveighoffer schveiguy at yahoo.com
Thu Mar 8 11:38:06 PST 2012


On Thu, 08 Mar 2012 13:17:15 -0500, Timon Gehr <timon.gehr at gmx.ch> wrote:

> On 03/08/2012 12:37 PM, Steven Schveighoffer wrote:
>> On Wed, 07 Mar 2012 19:06:14 -0500, Timon Gehr <timon.gehr at gmx.ch>  
>> wrote:
>>
>>> On 03/07/2012 11:37 PM, Stewart Gordon wrote:
>>>> On 07/03/2012 15:41, Steven Schveighoffer wrote:
>>>> <snip>
>>>>> In fact, I think this is valid D code:
>>>>>
>>>>> int i;
>>>>> const int *pi = &i;
>>>>> int *p = cast()pi;
>>>>> *p = 5; // legal because I know this points at i, and i is really
>>>>> mutable
>>>>
>>>> cast() is an abomination. I'm not sure OTTOMH whether it's a bug that  
>>>> it
>>>> works.
>>>>
>>>
>>> It is not legal code. I did not point it out because it was clear what
>>> was meant. cast() only casts away the top level of modifiers. It is
>>> perfectly safe except for class objects.
>>
>> If it's not legal code, then how is implicitly casting away inout during
>> function execution legal code? Isn't this the same thing?
>>
>> -Steve
>
> It is not legal code because the assignment const(int)* to int* does not  
> succeed.

Oh right, I forgot that casting using cast() just goes to the tail-const  
version.  grr... We really need const_cast...

> The other part is up to debate. The specification does not define the  
> semantics of casting away const and changing the data.

Yes, I couldn't really find that.  It does specifically say casting away  
const and then modifying is invalid, but it does not say anything about  
"if you know the underlying data is mutable".  But again, this is the  
point I was trying to make, we are casting away a const-like attribute and  
modifying the data.

> It is also not the same as with the proposed change to inout. inout  
> would not be 'removed' in the function body, it would be 'removed' upon  
> inout-matching the parameters. Inout should be able to replace overloads  
> on const, therefore I think that is the way it should work on the  
> conceptual level.

It is essentially the same as this:

void bar(const(int) * i, void delegate(const(int)* i) dg) {dg(i);}
void main()
{
    void foo(int *i) {*i = 5;}
    bar(&i, cast(delegate(const(int)*)) &foo);
}

Which I don't know if it's valid.  Given that compiler enforcement of  
inout being *sure* that the data is actually mutable, it's much safer than  
what I wrote above, but it's certainly no different.  It's just  
compiler-checked vs. manually checked.

-Steve


More information about the Digitalmars-d mailing list