ref const array error

jdrewsen jdrewsen at nospam.com
Thu Jan 19 12:33:37 PST 2012


On Thursday, 19 January 2012 at 17:00:59 UTC, Timon Gehr wrote:
> On 01/19/2012 03:47 PM, jdrewsen wrote:
>> On Wednesday, 18 January 2012 at 23:09:56 UTC, Timon Gehr 
>> wrote:
>>> On 01/18/2012 10:12 PM, jdrewsen wrote:
>>>> On Wednesday, 18 January 2012 at 20:13:04 UTC, Timon Gehr 
>>>> wrote:
>>>>> On 01/18/2012 08:59 PM, jdrewsen wrote:
>>>>>> On Wednesday, 18 January 2012 at 19:43:52 UTC, Timon Gehr 
>>>>>> wrote:
>>>>>>> On 01/18/2012 08:31 PM, jdrewsen wrote:
>>>>>>>> Recently the encoding.safeDecode stopped working for 
>>>>>>>> some of my
>>>>>>>> existing
>>>>>>>> code. This example outlines the issue:
>>>>>>>>
>>>>>>>> import std.encoding;
>>>>>>>>
>>>>>>>> void main(string[] args) {
>>>>>>>> auto e = EncodingScheme.create("utf-8");
>>>>>>>> auto a = new byte[100];
>>>>>>>> e.safeDecode(a);
>>>>>>>> }
>>>>>>>>
>>>>>>>> Results in:
>>>>>>>>
>>>>>>>> Error: function std.encoding.EncodingScheme.safeDecode 
>>>>>>>> (ref
>>>>>>>> const(ubyte)[] s) const is not callable using argument 
>>>>>>>> types
>>>>>>>> (byte[])
>>>>>>>>
>>>>>>>> Isn't this an error in the compiler?
>>>>>>>>
>>>>>>>> /Jonas
>>>>>>>>
>>>>>>>
>>>>>>> No, this is a bugfix. The operation is unsound:
>>>>>>>
>>>>>>> immutable(ubyte)[] foo(ref const(ubyte)[] s){
>>>>>>> auto r = new immutable(ubyte)[1];
>>>>>>> s = r;
>>>>>>> return r;
>>>>>>> }
>>>>>>>
>>>>>>> void main() {
>>>>>>> ubyte[] x;
>>>>>>> immutable(ubyte)[] y = foo(x);
>>>>>>> static assert(is(typeof(y[0])==immutable));
>>>>>>> auto oldy0 = y[0];
>>>>>>> x[0]=oldy0+1;
>>>>>>> assert(oldy0 == y[0]); // fail
>>>>>>> }
>>>>>>>
>>>>>>> The functionality is not going away; You will be able to 
>>>>>>> use inout
>>>>>>> for
>>>>>>> the same purpose once my enhancement request gets 
>>>>>>> implemented:
>>>>>>> http://d.puremagic.com/issues/show_bug.cgi?id=7105
>>>>>>
>>>>>> Wouldn't a nicer solution be to let the compiler ensure 
>>>>>> that
>>>>>> an immutable array cannot escape through a ref const array 
>>>>>> parameter?
>>>>>>
>>>>>> /Jonas
>>>>>>
>>>>>
>>>>> That would not suffice.
>>>>>
>>>>> ubyte[] foo(ref const(ubyte)[] s){
>>>>> auto r = new ubyte[1];
>>>>> s = r;
>>>>> return r;
>>>>> }
>>>>>
>>>>> void main() {
>>>>> immutable(ubyte)[] x;
>>>>> ubyte[] y = foo(x);
>>>>> static assert(is(typeof(x[0])==immutable));
>>>>> auto oldx0 = x[0];
>>>>> y[0]=oldx0+1;
>>>>> assert(oldx0 == x[0]); // fail
>>>>> }
>>>>
>>>> In the example foo is actually using the ref s parameter as 
>>>> an out
>>>> parameter. The compiler could catch that you're doing this 
>>>> and show an
>>>> error.
>>>>
>>>> This would force you to let foo look like:
>>>>
>>>> ubyte[] foo(out const(ubyte)[] s);
>>>>
>>>> Wouldn't that fix it?
>>>>
>>>>
>>>
>>> If it is ref or out is irrelevant for the example, so how 
>>> would this
>>> fix anything? The compiler could, in principle, treat const 
>>> similarly
>>> to inout (just without the context sensitivity and parameter 
>>> matching
>>> etc) for 'ref' parameters and do all the type checking at the 
>>> call
>>> site. However, that would then restrict what the callee can 
>>> do and
>>> introduce a strange special case. inout is the way to go.
>>
>> But in the example you're using s as an out parameter and that 
>> should
>> trigger the error I got originally of course. But if ref 
>> parameters were
>> disallowed to be used as out parameters the compiler would 
>> catch the
>> error in your example wouldn't it?
>>
>>
>
> The compiler would catch something in my example, but not the 
> error. The error happens at the call site.

Actually when I think about it using semantic for out/ref that I 
suggested does not solve the problem at all. I guess the inout 
thing is the way to go.

A pitty that safeDecode only supports the ref const(ubyte)[] 
version and not ref ubyte[]. I wonder how big of an issue this is 
for the rest of phobos functions accepting ref parameters.

/Jonas



More information about the Digitalmars-d mailing list