www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Automatic void initialization

reply Fractal <void server.com> writes:
Hello

if I have the following code:

int foo;
foo = 5;

When the variable foo is declared, it is initialized to int.init, or has
garbage contents until it is assigned?

Thanks
May 31 2009
next sibling parent reply Jason House <jason.james.house gmail.com> writes:
Fractal wrote:

 Hello
 
 if I have the following code:
 
 int foo;
 foo = 5;
 
 When the variable foo is declared, it is initialized to int.init, or has
 garbage contents until it is assigned?
 
 Thanks
D will always initialize variables unless you explicitly tell it not to. (although a smart compiler may optimize certain cases) Here's how to get foo initialized to garbage: int foo = void; foo = 5;
May 31 2009
parent reply Walter Bright <newshound1 digitalmars.com> writes:
Jason House wrote:
 D will always initialize variables unless you explicitly tell it not to. 
 (although a smart compiler may optimize certain cases)
Dead assignment elimination is compiler technology from the 70's !
Jun 02 2009
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
Dead assignment elimination is compiler technology from the 70's !<
I'd like to see this technology used for arrays too. So in the following two adjacent lines of code "a" doesn't get initialized to zero before being initialized again to 5: void main() { auto a = new int[10]; a[] = 5; printf("%d\n", a[3]); } The ASM: sub ESP,01Ch mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ push 0Ah push EAX call near ptr __d_newarrayT mov 0Ch[ESP],EAX mov 010h[ESP],EDX push dword ptr 0Ch[ESP] push 5 push EDX mov 014h[ESP],EDX call near ptr __memset32 mov ECX,014h[ESP] mov EDX,offset FLAT:_DATA push dword ptr 0Ch[ECX] push EDX call near ptr _printf [...] Bye, bearophile
Jun 02 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Jun 2, 2009 at 8:10 AM, bearophile <bearophileHUGS lycos.com> wrote=
:
 Walter Bright:
Dead assignment elimination is compiler technology from the 70's !<
I'd like to see this technology used for arrays too. So in the following =
two adjacent lines of code "a" doesn't get initialized to zero before being= initialized again to 5:
 void main() {
 =A0 =A0auto a =3D new int[10];
 =A0 =A0a[] =3D 5;
 =A0 =A0printf("%d\n", a[3]);
 }

 The ASM:

 sub ESP,01Ch
 mov EAX,offset FLAT:_D11TypeInfo_Ai6__initZ
 push 0Ah
 push EAX
 call near ptr __d_newarrayT
 mov 0Ch[ESP],EAX
 mov 010h[ESP],EDX
 push dword ptr 0Ch[ESP]
 push 5
 push EDX
 mov 014h[ESP],EDX
 call near ptr __memset32
 mov ECX,014h[ESP]
 mov EDX,offset FLAT:_DATA
 push dword ptr 0Ch[ECX]
 push EDX
 call near ptr _printf
 [...]
As far as I know, LDC already does this.
Jun 02 2009
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jarrett Billingsley wrote:
 On Tue, Jun 2, 2009 at 8:10 AM, bearophile <bearophileHUGS lycos.com> wrote:
 Walter Bright:
 Dead assignment elimination is compiler technology from the 70's !<
I'd like to see this technology used for arrays too. So in the following two adjacent lines of code "a" doesn't get initialized to zero before being initialized again to 5: void main() { auto a = new int[10]; a[] = 5; printf("%d\n", a[3]); }
As far as I know, LDC already does this.
It doesn't. The runtime call that allocates the array initializes it (to 0 in this case), and then the array assignment overwrites that initialization. In this case the array doesn't escape the function, so it does get stack-allocated by a custom optimization pass (and the initialization is turned into an LLVM memset intrinsic), but LLVM still can't "look into" the call that does the array assignment to know it will always overwrite the entire array so the memset isn't necessary.
Jun 02 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Jun 2, 2009 at 10:41 AM, Frits van Bommel
<fvbommel remwovexcapss.nl> wrote:
 Jarrett Billingsley wrote:
 On Tue, Jun 2, 2009 at 8:10 AM, bearophile <bearophileHUGS lycos.com>
 wrote:
 Walter Bright:
 Dead assignment elimination is compiler technology from the 70's !<
I'd like to see this technology used for arrays too. So in the followin=
g
 two adjacent lines of code "a" doesn't get initialized to zero before b=
eing
 initialized again to 5:

 void main() {
 =A0 auto a =3D new int[10];
 =A0 a[] =3D 5;
 =A0 printf("%d\n", a[3]);
 }
As far as I know, LDC already does this.
It doesn't. The runtime call that allocates the array initializes it (to =
0
 in this case), and then the array assignment overwrites that initializati=
on.
 In this case the array doesn't escape the function, so it does get
 stack-allocated by a custom optimization pass (and the initialization is
 turned into an LLVM memset intrinsic), but LLVM still can't "look into" t=
he
 call that does the array assignment to know it will always overwrite the
 entire array so the memset isn't necessary.
I thought I remember seeing a runtime function to allocate an array without initializing it.. maybe it's just not used yet?
Jun 02 2009
next sibling parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Jarrett Billingsley wrote:
 I thought I remember seeing a runtime function to allocate an array
 without initializing it.. maybe it's just not used yet?
Oh, the function's there. It's just not used for that purpose :P. It's used for array concatenations and array literals, where the compiler can tell from a single expression that the default initialization will always be useless since it'll be overwritten immediately.
Jun 02 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jarrett Billingsley:
 I thought I remember seeing a runtime function to allocate an array
 without initializing it.. maybe it's just not used yet?
Splitting the array allocation and the memset32, a successive optimization pass of the compiles may be able to simplify code like: auto a = new int[n]; a[] = 10; a[] = 20; In a single allocation + one memset32, instead of allocation + 3 memsets32. But in most situations this isn't a critical optimization, so it's low priority. Bye, bearophile
Jun 02 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Walter Bright wrote:
 Jason House wrote:
 D will always initialize variables unless you explicitly tell it not 
 to. (although a smart compiler may optimize certain cases)
Dead assignment elimination is compiler technology from the 70's !
Although the technology didn't make it to the PC until 1985 with the release of Datalight Optimum C. But still, that's 24 years ago!
Jun 02 2009
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Tue, 02 Jun 2009 23:20:06 +0400, Walter Bright <newshound1 digitalmars.com>
wrote:

 Walter Bright wrote:
 Jason House wrote:
 D will always initialize variables unless you explicitly tell it not  
 to. (although a smart compiler may optimize certain cases)
Dead assignment elimination is compiler technology from the 70's !
Although the technology didn't make it to the PC until 1985 with the release of Datalight Optimum C.
Which became Zortech C++ which became Symantec C++?
 But still, that's 24 years ago!
Jun 02 2009
parent Walter Bright <newshound1 digitalmars.com> writes:
Denis Koroskin wrote:
 On Tue, 02 Jun 2009 23:20:06 +0400, Walter Bright <newshound1 digitalmars.com>
wrote:
 Although the technology didn't make it to the PC until 1985 with the  
 release of Datalight Optimum C.
Which became Zortech C++ which became Symantec C++?
Yes.
Jun 02 2009
prev sibling next sibling parent BCS <none anon.com> writes:
Hello Fractal,

 Hello
 
 if I have the following code:
 
 int foo;
 foo = 5;
 When the variable foo is declared, it is initialized to int.init, or
 has garbage contents until it is assigned?
 
 Thanks
 
int.init unless the compiler rewrites it as int foo = 5; and then 5.
May 31 2009
prev sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Fractal wrote:
 if I have the following code:
 
 int foo; foo = 5;
 
 When the variable foo is declared, it is initialized to int.init, or
 has garbage contents until it is assigned?
Here's the easy way to find out: int bar() { int foo; foo = 5; return foo; } compile with: dmd -c test -O -release and disassemble with: obj2asm test.obj to show the generated code is: _D4test3barFZi comdat mov EAX,5 ret
Jun 02 2009