www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - LDC, ARM: unnecessary default initialization

reply Jack Applegame <japplegame gmail.com> writes:
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}

    4:   466c            mov     r4, sp                   | 
default initialization

    a:   4620            mov     r0, r4                   | WHY???
    c:   f7ff fffe       bl      0 <__aeabi_memclr4>     -+





   1e:   d1f8            bne.n   12 <_D4test12ResetHandlerFZv+0x12>

   22:   bd10            pop     {r4, pc}
*****************************************
Aug 18 2017
parent reply kinke <kinke gmx.net> writes:
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.
Aug 18 2017
next sibling parent reply kinke <noone nowhere.com> writes:
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); }
Aug 18 2017
parent Jack Applegame <japplegame gmail.com> writes:
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>: 4: 4669 mov r1, sp 12: d1f8 bne.n 6 <_D4test12ResetHandlerFZv+0x6> 16: 4770 bx lr ****************************************
Aug 19 2017
prev sibling parent reply Johan Engelen <j j.nl> writes:
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
Aug 22 2017
parent Johan Engelen <j j.nl> writes:
On Tuesday, 22 August 2017 at 18:26:46 UTC, Johan Engelen wrote:
 
 It was discussed briefly during my DConf 2016 talk
2017.
Aug 22 2017