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?







Reply via email to