transporting qualifier from parameter to the return value

Steven Schveighoffer schveiguy at yahoo.com
Wed Dec 16 11:02:35 PST 2009


On Wed, 16 Dec 2009 09:21:16 -0500, Michel Fortin  
<michel.fortin at michelf.com> wrote:

> On 2009-12-16 08:54:03 -0500, "Denis Koroskin" <2korden at gmail.com> said:
>
>>> I just realized that 'inout' could have a real use even for functions   
>>> with no return value. Consider this:
>>>  	void doSomething(inout(Object)[] a, inout(Object)[] b) {
>>> 		a[0] = b[0]; // works only when objects in both arrays have the  
>>> same  constness.
>>> 	}
>>  Doesn't work.
>>  doSomething("hello", "world");
>
> Well, of course it doesn't...
>
> Here's what I meant:
>
> 	void doSomething(inout(MyStruct)*[] a, inout(MyStruct)*[] b) {
> 		a[0] = b[0]; // works only when structs in both arrays have the same  
> constness.
> 	}

This is dangerous.

We should figure out a reason why this shouldn't compile.  It's hard for  
me to wrap my head around it.  Either the implicit cast when calling the  
function shouldn't work, or the assignment shouldn't work.  My intuition  
is that the implicit cast should fail.

Consider the following function with today's notation:

void doSomething(const(MyStruct)*[] a, const(MyStruct*)[] b) {
   a[0] = b[0];
}

Now:

immutable(MyStruct)*[] im;
MyStruct*[] mut;

MyStruct *s = new MyStruct;
mut ~= s;

im.length = 1;

doSomething(im, mut);

Oops, without a cast, we have changed s into an immutable struct.  Hidden  
inside a function no less!

Does this code compile today?  If so, we need to fix this.  With this  
fixed, the inout version naturally becomes invalid.

-Steve




More information about the Digitalmars-d mailing list