simplified case:

doesn't work with NRVO:
void main(){
    immutable int[10] x = () pure {
        int[10] x_;
        debug printf("&x_[0] = %p\n", &x_[0]);
        return x_;
    }();
    debug printf("&x[0] = %p\n", &x[0]);  // prints different address
}
 


doesn't work with RVO:
struct A{
    int[10] x_;
    this(int _ignore)pure{
        foo();
    }
    void foo()const pure{
        debug printf("&x_[0] = %p\n", &x_[0]);
    }
}
void main(){
    immutable A a = () pure {
        return A(0);
    }();
    a.foo();
}
 

is RVO even happening?

On Thu, May 16, 2013 at 1:55 AM, Kenji Hara <k.hara.pg@gmail.com> wrote:
2013/5/16 TommiT <tommitissari@hotmail.com>
I'd like to make it easier to initialize function local immutable/const data. Here's the type of problem I'd like to alleviate:

const string[100] int__str;
const int[string] str__int;

for (int i = 0; i < 100; ++i)
{
    auto str = to!string(i);
    int__str[i] = str; // ERROR: Can't modify const
    str__int[str] = i; // ERROR: Can't modify const
}

In short, I want to initialize two different const variables at once (in the same loop or other block). If I needed to initialize only one const variable, I could use a lambda:

const string[100] int__str = {
    string[100] tmp;
    // ... init tmp ...
    return tmp;
}();

...But I can't see any easy solution for initializing two or more const variables at the same time.

Here's my proposal: "initialization scope". You'd use it like this:

initialization {
    const string[100] int__str;
    const int[string] str__int;

    for (int i = 0; i < 100; ++i)
    {
        auto str = to!string(i);
        int__str[i] = str; // OK
        str__int[str] = i; // OK
    }
}

string s = int__str[42]; // OK
int__str[42] = "43" // ERROR: Can't modify const

As you can see, 'initialization scope' would be a scope that is not a lexical scope (like static if), it merely makes all const and immutable variables created in that scope modifiable inside that scope but not after it.

Pure delegate and implicit conversion for unique expression should work.

import std.conv;
void main()
{
    immutable string[100] int__str = () pure {
        string[100] tmp;
        debug printf("&tmp[0] = %p\n", &tmp[0]);        // [1]
        for (int i = 0; i < 100; ++i)
        {
            auto str = to!string(i);
            // BUG: pure function '__lambda1' cannot call impure function 'to'
            tmp[i] = str;
        }
        return tmp; // BUG: NRVO doesn't work
    }();
    debug printf("&int__str[0] = %p\n", &int__str[0]);  // [2]
}

Compiler bug: Currently [1] and [2] does not print same address.
Phobos bug: Currently std.conv.to is not pure.

Kenji Hara