October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #10 from rswhite4@googlemail.com 2013-10-30 01:44:17 PDT ---
Couldn't the compiler to this dirty trick for me?
If he found such multiple init case, he could rewrite the code. So that this
code:
----
this(int x, size_t i) {
    arr[0] = x;
    arr[1] = x + 1;
    arr[i] = x + 2;  // which index will be initialized in runtime?
}
----

if rewritten to this:

this(int x, size_t i) {
     Unqual!typeof(arr) __arr = null;

    __arr[0] = x;
    __arr[1] = x + 1;
    __arr[i] = x + 2;

    this.arr = __arr; /// only _one_ assignment
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #11 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-30 01:49:54 PDT ---
(In reply to comment #10)
> Couldn't the compiler to this dirty trick for me?
> If he found such multiple init case, he could rewrite the code. So that this
> code:
> ----
> this(int x, size_t i) {
>     arr[0] = x;
>     arr[1] = x + 1;
>     arr[i] = x + 2;  // which index will be initialized in runtime?
> }
> ----
> 
> if rewritten to this:
> 
> this(int x, size_t i) {
>      Unqual!typeof(arr) __arr = null;
> 
>     __arr[0] = x;
>     __arr[1] = x + 1;
>     __arr[i] = x + 2;
> 
>     this.arr = __arr; /// only _one_ assignment
> }

That would be a bad behavior when the size of arr field is quite big, because it will silently consume stack memory. I can believe someone will hate it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #12 from rswhite4@googlemail.com 2013-10-30 01:52:32 PDT ---
(In reply to comment #11)
> (In reply to comment #10)
> > Couldn't the compiler to this dirty trick for me?
> > If he found such multiple init case, he could rewrite the code. So that this
> > code:
> > ----
> > this(int x, size_t i) {
> >     arr[0] = x;
> >     arr[1] = x + 1;
> >     arr[i] = x + 2;  // which index will be initialized in runtime?
> > }
> > ----
> > 
> > if rewritten to this:
> > 
> > this(int x, size_t i) {
> >      Unqual!typeof(arr) __arr = null;
> > 
> >     __arr[0] = x;
> >     __arr[1] = x + 1;
> >     __arr[i] = x + 2;
> > 
> >     this.arr = __arr; /// only _one_ assignment
> > }
> 
> That would be a bad behavior when the size of arr field is quite big, because it will silently consume stack memory. I can believe someone will hate it.

Who?
It's the best approach I have currently. There must be a way to weaken the
effects of this change.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #13 from bearophile_hugs@eml.cc 2013-10-30 02:43:17 PDT ---
(In reply to comment #8)

>     this(int x) {
>         static int[3] make(int x) pure {
>             int[3] a;
>             a[0] = x;
>             a[1] = x + 1;
>             a[2] = x + 2;
>         }
>         this.arr = make(x);  // NRVO works
>     }


A little test program:

struct Foo {
    int[3] arr;
    this(int x) pure nothrow {
        arr[0] = x;
        arr[1] = x + 1;
        arr[2] = x + 2;
    }
}
struct Bar {
    immutable int[3] arr;

    this(int x) pure nothrow {
        static int[3] make(in int x) pure nothrow {
            typeof(return) a;
            a[0] = x;
            a[1] = x + 1;
            a[2] = x + 2;
            return a;
        }

        this.arr = make(x);  // NRVO works
    }
}
void main() {
    auto f = Foo(5);
    auto b = Bar(5);
}


The asm of its struct constructors using dmd:
dmd -O -release -inline -noboundscheck test.d


Foo.__ctor:
    push EBX
    mov EDX, EAX
    mov EBX, 8[ESP]
    push ESI
    lea ECX, 1[EBX]
    lea ESI, 2[EBX]
    mov [EDX], EBX
    mov 4[EDX], ECX
    mov 8[EDX], ESI
    pop ESI
    pop EBX
    ret 4


Bar.__ctor:
    sub ESP, 010h
    xor EDX, EDX
    push EBX
    mov EBX, 018h[ESP]
    push ESI
    lea ESI, 1[EBX]
    push EDI
    lea EDI, 2[EBX]
    mov 018h[ESP], EAX
    push 0Ch
    lea ECX, 010h[ESP]
    mov [ECX], EDX
    mov 4[ECX], EDX
    mov 8[ECX], EDX
    mov 010h[ESP], EBX
    mov 014h[ESP], ESI
    mov 018h[ESP], EDI
    push ECX
    push EAX
    call near ptr _memcpy
    add ESP, 0Ch
    mov EAX, 018h[ESP]
    pop EDI
    pop ESI
    pop EBX
    add ESP, 010h
    ret 4

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #14 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-30 03:00:47 PDT ---
(In reply to comment #12)
> Who?

Embedded system programmers, for example.

---

We can add some acceptable cases certainly. For example, by the following rule:
"If the static array field is initialized
  1. with different compile-time constant indices, and
  2. each initializing expressions does not have overlapping
     with each other over the whole control-flow paths
     in the constructor"
the bearophile's case may be allowed.

But, it's very complex and heuristic rule, and will covers just only a few
cases.
We must reject heuristic rule, because it is hard to maintain and verify
language semantics.

That's the matter of cost-benefit ratio.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #15 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-30 03:12:27 PDT ---
(In reply to comment #13)
> (In reply to comment #8)
> 
> A little test program:
[snip]

Hmm, strange. After moving out the nested static function 'make' to module level, I got this generated code.

struct Foo {
    int[3] arr;
    this(int x) pure nothrow {
        arr[0] = x;
        arr[1] = x + 1;
        arr[2] = x + 2;
    }
}
// move out to module level
static int[3] make(in int x) pure nothrow {
    typeof(return) a;
    a[0] = x;
    a[1] = x + 1;
    a[2] = x + 2;
    return a;
}
struct Bar {
    immutable int[3] arr;

    this(int x) pure nothrow {
        this.arr = make(x);  // NRVO works?
    }
}
void main() {
    auto f = Foo(5);
    auto b = Bar(5);
}

Assembly:

C:\Users\khara\d\test.d:23 void main() {
0040209c: 83ec24                  sub esp, 0x24
0040209f: 31c9                    xor ecx, ecx
004020a1: ba05000000              mov edx, 0x5
004020a6: 53                      push ebx
004020a7: bb06000000              mov ebx, 0x6
004020ac: 56                      push esi

C:\Users\khara\d\test.d:24     auto f = Foo(5);
004020ad: 8d442408                lea eax, [esp+0x8]
004020b1: be07000000              mov esi, 0x7
004020b6: 8908                    mov [eax], ecx
004020b8: 894804                  mov [eax+0x4], ecx
004020bb: 894808                  mov [eax+0x8], ecx
C:\Users\khara\d\test.d:4         arr[0] = x;
004020be: 8d442414                lea eax, [esp+0x14]
004020c2: 89542408                mov [esp+0x8], edx
C:\Users\khara\d\test.d:5         arr[1] = x + 1;
004020c6: 31d2                    xor edx, edx
004020c8: 895c240c                mov [esp+0xc], ebx
C:\Users\khara\d\test.d:6         arr[2] = x + 2;
004020cc: 89742410                mov [esp+0x10], esi

C:\Users\khara\d\test.d:25     auto b = Bar(5);
004020d0: 6a0c                    push 0xc
C:\Users\khara\d\test.d:20         this.arr = make(x);  // NRVO works?
004020d2: 8908                    mov [eax], ecx
004020d4: 894804                  mov [eax+0x4], ecx
004020d7: 894808                  mov [eax+0x8], ecx
004020da: 8d4c2424                lea ecx, [esp+0x24]
004020de: 8911                    mov [ecx], edx
004020e0: 895104                  mov [ecx+0x4], edx
004020e3: 895108                  mov [ecx+0x8], edx
C:\Users\khara\d\test.d:11     a[0] = x;
004020e6: c744242405000000        mov dword [esp+0x24], 0x5
C:\Users\khara\d\test.d:12     a[1] = x + 1;
004020ee: 895c2428                mov [esp+0x28], ebx
C:\Users\khara\d\test.d:13     a[2] = x + 2;
004020f2: 8974242c                mov [esp+0x2c], esi
C:\Users\khara\d\test.d:10     typeof(return) a;
004020f6: 51                      push ecx
004020f7: 50                      push eax
004020f8: e8e3110100              call 0x4132e0 _memmove  // still exists...!
004020fd: 83c40c                  add esp, 0xc

C:\Users\khara\d\test.d:26 }
00402100: 31c0                    xor eax, eax
00402102: 5e                      pop esi
00402103: 5b                      pop ebx
00402104: 83c424                  add esp, 0x24
00402107: c3                      ret


In 2.064a, the bug 10094 has been fixed. However we need to fix these (at least two orthogonal) bugs for the next release.

I'll open new issues for them.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 30, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=11343



--- Comment #16 from bearophile_hugs@eml.cc 2013-10-30 16:49:40 PDT ---
(In reply to comment #15)

> In 2.064a, the bug 10094 has been fixed. However we need to fix these (at least two orthogonal) bugs for the next release.
> 
> I'll open new issues for them.


Something perhaps related:


import std.algorithm: copy;
immutable int[2] data;
static this() {
    [10, 20].copy(data[]); // Error.
}
void main() {}


Thread: http://forum.dlang.org/thread/iaxjrzxktoeldifrwzgr@forum.dlang.org

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2
Next ›   Last »