std.conv.to!string(array), strange compile error
anonymous via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Nov 14 10:52:54 PST 2015
On 14.11.2015 15:40, Relja wrote:
> float[3] array;
> array.to!string; // compiles
Alright, full test case:
----
import std.conv;
float[3] getFloat3() {
return [1, 2, 3];
}
void main() {
getFloat3().to!string; // does not compile
float[3] a;
a.to!string; // compiles
}
----
Yeah, that's odd.
Looking at std.conv, `to` is this [1]:
----
template to(T)
{
T to(A...)(A args)
if (!isRawStaticArray!A)
{
return toImpl!T(args);
}
// Fix issue 6175
T to(S)(ref S arg)
if (isRawStaticArray!S)
{
return toImpl!T(arg);
}
}
----
So static arrays are taken by reference. That explains why return values
from functions are rejected: they're rvalues and can't be passed by
reference.
Apparently, that oddity is a fix for issue 6175 [2] which seems to be
about `to` returning a slice of a local variable (which is bad). I don't
know the details of the issue or the fix, but I've got a feeling that
there must be a better fix.
Taking the data by reference, but otherwise doing the same as before
would mean that `to` simply slices a static array when asked to make a
dynamic array of it, rather than copying the data. And indeed, that
seems to be the case:
----
float[] f()
{
import std.conv;
float[3] a = [1, 2, 3];
return a.to!(float[]);
}
void main()
{
auto a = f();
import std.stdio;
writeln(a); /* prints garbage */
}
----
I don't know if that's considered acceptable. I'm not a fan.
[1]
https://github.com/D-Programming-Language/phobos/blob/48d57e36e74379291a52087fcd1aa0dc19ff9a70/std/conv.d#L293-L307
[2] https://issues.dlang.org/show_bug.cgi?id=6175
More information about the Digitalmars-d-learn
mailing list