Thread overview
LDC, ARM: unnecessary default initialization
Aug 18, 2017
Jack Applegame
Aug 18, 2017
kinke
Aug 18, 2017
kinke
Aug 19, 2017
Jack Applegame
Aug 22, 2017
Johan Engelen
Aug 22, 2017
Johan Engelen
August 18, 2017
I explore the possibility of using D for bare metal ARM programming.

For some reason, the LDC default initializes the structure, even if initialization of all its members is specified as void. I believe that this is wrong.

test.d
****************************************
module test;

import core.bitop : volatileStore;

struct Foo {
	uint[64] m = void; // no default initialization
	this(uint a) {
		foreach(ref b; m) volatileStore(&b,a++);
	}
}

void ResetHandler() {
	auto foo = Foo(10);
}
****************************************

$ldc2 -mtriple=thumb-none-linux-eabi -mcpu=cortex-m3 -c --betterC --boundscheck=off -relocation-model=static -O3 -vcolumns test.d

test.o assembly
****************************************
00000000 <_D4test12ResetHandlerFZv>:
   0:   b510            push    {r4, lr}
   2:   b0c0            sub     sp, #256        ; 0x100 -+
   4:   466c            mov     r4, sp                   | default initialization
   6:   f44f 7180       mov.w   r1, #256        ; 0x100  |
   a:   4620            mov     r0, r4                   | WHY???
   c:   f7ff fffe       bl      0 <__aeabi_memclr4>     -+
  10:   2000            movs    r0, #0
  12:   f100 010a       add.w   r1, r0, #10
  16:   f844 1020       str.w   r1, [r4, r0, lsl #2]
  1a:   3001            adds    r0, #1
  1c:   2949            cmp     r1, #73 ; 0x49
  1e:   d1f8            bne.n   12 <_D4test12ResetHandlerFZv+0x12>
  20:   b040            add     sp, #256        ; 0x100
  22:   bd10            pop     {r4, pc}
*****************************************


August 18, 2017
On Friday, 18 August 2017 at 09:42:25 UTC, Jack Applegame wrote:
> For some reason, the LDC default initializes the structure, even if initialization of all its members is specified as void. I believe that this is wrong.

Afaik, this has been brought up multiple times already and is so by design. Every aggregate has an init symbol, omitting that (and accordingly the default initialization of all instances) by initializing each field with void doesn't work. The initialization isn't performed fieldwise, but is a bitcopy of T.init.
You can skip initialization of specific instances though - `S s = void;` - but again not if `s` is a field of another aggregate.
August 18, 2017
On Friday, 18 August 2017 at 12:09:04 UTC, kinke wrote:
> On Friday, 18 August 2017 at 09:42:25 UTC, Jack Applegame wrote:
>> For some reason, the LDC default initializes the structure, even if initialization of all its members is specified as void. I believe that this is wrong.
>
> Afaik, this has been brought up multiple times already and is so by design. Every aggregate has an init symbol, omitting that (and accordingly the default initialization of all instances) by initializing each field with void doesn't work. The initialization isn't performed fieldwise, but is a bitcopy of T.init.
> You can skip initialization of specific instances though - `S s = void;` - but again not if `s` is a field of another aggregate.

Sorry, I forgot some workaround code:

void ResetHandler() {
    Foo foo = void;
    foo.__ctor(10);
    // or: std.conv.emplace(&foo, 10);
}
August 19, 2017
On Friday, 18 August 2017 at 17:28:38 UTC, kinke wrote:
> On Friday, 18 August 2017 at 12:09:04 UTC, kinke wrote:
>> On Friday, 18 August 2017 at 09:42:25 UTC, Jack Applegame wrote:
>>> For some reason, the LDC default initializes the structure, even if initialization of all its members is specified as void. I believe that this is wrong.
>>
>> Afaik, this has been brought up multiple times already and is so by design. Every aggregate has an init symbol, omitting that (and accordingly the default initialization of all instances) by initializing each field with void doesn't work. The initialization isn't performed fieldwise, but is a bitcopy of T.init.
>> You can skip initialization of specific instances though - `S s = void;` - but again not if `s` is a field of another aggregate.
>
> Sorry, I forgot some workaround code:
>
> void ResetHandler() {
>     Foo foo = void;
>     foo.__ctor(10);
>     // or: std.conv.emplace(&foo, 10);
> }
Thanks for the answer. Also I found another workaround code:

test.d
****************************************
module test;

import core.bitop : volatileStore;

struct Foo {
	uint[64] m = void; // no default initialization
	static auto opCall(uint a) {
		Foo foo = void;
		foreach(ref b; foo.m) volatileStore(&b,a++);
		return foo;
	}
}

void ResetHandler() {
	auto foo = Foo(10);
}
****************************************

assembly
****************************************
00000000 <_D4test12ResetHandlerFZv>:
   0:   b0c0            sub     sp, #256        ; 0x100
   2:   2000            movs    r0, #0
   4:   4669            mov     r1, sp
   6:   f100 020a       add.w   r2, r0, #10
   a:   f841 2020       str.w   r2, [r1, r0, lsl #2]
   e:   3001            adds    r0, #1
  10:   2a49            cmp     r2, #73 ; 0x49
  12:   d1f8            bne.n   6 <_D4test12ResetHandlerFZv+0x6>
  14:   b040            add     sp, #256        ; 0x100
  16:   4770            bx      lr
****************************************



August 22, 2017
On Friday, 18 August 2017 at 12:09:04 UTC, kinke wrote:
> On Friday, 18 August 2017 at 09:42:25 UTC, Jack Applegame wrote:
>> For some reason, the LDC default initializes the structure, even if initialization of all its members is specified as void. I believe that this is wrong.
>
> Afaik, this has been brought up multiple times already and is so by design.

https://issues.dlang.org/show_bug.cgi?id=11331
https://issues.dlang.org/show_bug.cgi?id=11817
https://issues.dlang.org/show_bug.cgi?id=15951

It was discussed briefly during my DConf 2016 talk, and the status is that it is considered a performance bug. But it'll require spec changes / clarifications; Johannes listed a number already and maybe more it needed.

- Johan

August 22, 2017
On Tuesday, 22 August 2017 at 18:26:46 UTC, Johan Engelen wrote:
> 
> It was discussed briefly during my DConf 2016 talk

2017.