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