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

Reply via email to