ref const array error

Timon Gehr timon.gehr at gmx.ch
Thu Jan 19 12:37:32 PST 2012


On 01/19/2012 09:33 PM, jdrewsen wrote:
> 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
>

Probably they should eventually be fixed to use inout instead.


More information about the Digitalmars-d mailing list