transporting qualifier from parameter to the return value

Steven Schveighoffer schveiguy at yahoo.com
Wed Dec 16 12:38:56 PST 2009


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

> On 2009-12-16 14:02:35 -0500, "Steven Schveighoffer"  
> <schveiguy at yahoo.com> said:
>
>> On Wed, 16 Dec 2009 09:21:16 -0500, Michel Fortin   
>> <michel.fortin at michelf.com> wrote:
>>
>>> 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.
>
> If you're trying to define a ruke it's simple: you can cast immutable to  
> const only on the first level of indirection, or when there is no  
> indirection. So basically those conversions should be allowed:
>
> 	immutable(MyStruct)*[] -> const(MyStruct*)[]
> 	immutable(MyStruct*)[] -> const(MyStruct*)[]
> 	immutable(MyStruct*[]) -> const(MyStruct*[])
>

That sounds correct.

>
>
>> Does this code compile today?  If so, we need to fix this.  With this   
>> fixed, the inout version naturally becomes invalid.
>
> Just did a couple of small tests. Apparently everything is all right:
>
> 	test.d(18): Error: cannot implicitly convert expression (a) of type  
> immutable(int)*[] to const(int)*[]
>
> Also:
>
> 	test.d(18): Error: cannot implicitly convert expression (b) of type  
> int*[] to const(int)*[]
>
> Which is right otherwise you could assign immutable values to the array  
> others see as mutable. Also, converting from immutable(int)*[] to  
> const(int*)[] implicitly works fine and does prevent dangerous  
> assignments.
>
> So I don't think there is anything to fix on this front.
>

I did some testing too.  This compiles, which should be a bug:


import std.stdio;

void myfunc(const(int)[][]a, const(int)[][]b)
{
     a[0]= b[0];
}

void main()
{
     immutable(int)[][] i1;
     i1.length = 1;
     int [][]i2;
     i2 ~= [5];

     myfunc(i1, i2);
     writefln("%d", i1[0][0]);
     i2[0][0] = 6;
     writefln("%d", i1[0][0]);
}

Writes:
5
6

I think it has something to do with array casting rules.  Because you can  
cast just the pointer part of the array struct, it appears that these  
cases aren't considered the same as the pointer casting as you  
demonstrated.

I'll look for a bug on this, and if not, I'll add one.

-Steve



More information about the Digitalmars-d mailing list