ref const array error

Timon Gehr timon.gehr at gmx.ch
Wed Jan 18 15:09:56 PST 2012


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.


More information about the Digitalmars-d mailing list