www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static initialization question

reply Weed <resume755 mail.ru> writes:
moved from digitalmars.D

 Re: static initialization question 	Digital Mars
 Benjamin Shropshire (ao pathlink.com) 	2008/12/10 16:46
 Reply to Weed,

 why I can not initialize static variable this way:

 static MyClass c = new MyClass;

 Error: non-constant expression new MyClass

 (dmd 2.014)

this NG is more or less dead. The digitalmars.d.learn NGs would be a better choice. Only compile time constant values are legal for static initializers because they are initialized at compile time as part of the static data segments.

But my class does not contain data that need initialization and can be created in compile time
Dec 10 2008
parent reply Weed <resume755 mail.ru> writes:
code:

import std.stdio;

class MyClass
{
    invariant uint a = 0;
}

void main()
{
    static MyClass c = new MyClass;
    writeln( c.a );
}
Dec 10 2008
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 11 Dec 2008 01:31:32 +0300, Weed <resume755 mail.ru> wrote:

 But my class does not contain data that need initialization and can be created
 in compile time

 code:

 import std.stdio;

 class MyClass
 {
     invariant uint a = 0;
 }

 void main()
 {
     static MyClass c = new MyClass;
     writeln( c.a );
 }

There is a memory allocation that may occurs at run time only.
Dec 10 2008
prev sibling next sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Wed, Dec 10, 2008 at 5:31 PM, Weed <resume755 mail.ru> wrote:
 code:

 import std.stdio;

 class MyClass
 {
    invariant uint a = 0;
 }

 void main()
 {
    static MyClass c = new MyClass;
    writeln( c.a );
 }

It's not the class member that wants static initialization, it's your variable declaration. static MyClass c = new MyClass; This is illegal because static variables must be initialized with compile-time constants. The simple way around this is: static MyClass c; // defaults to null c = new MyClass; Which separates the declaration from initialization.
Dec 10 2008
next sibling parent BCS <ao pathlink.com> writes:
Reply to Jarrett,

 On Wed, Dec 10, 2008 at 5:31 PM, Weed <resume755 mail.ru> wrote:
 
 code:
 
 import std.stdio;
 
 class MyClass
 {
 invariant uint a = 0;
 }
 void main()
 {
 static MyClass c = new MyClass;
 writeln( c.a );
 }

variable declaration. static MyClass c = new MyClass; This is illegal because static variables must be initialized with compile-time constants. The simple way around this is: static MyClass c; // defaults to null c = new MyClass; Which separates the declaration from initialization.

As long as you do this in main it works. In other functions (that might get called more than once) you will need to do something else. Ripping the variable out of the function would let you use a static constructor: class MyClass { invariant uint a = 0; } MyClass c; static this() { c = new MyClass; } void main() { writeln( c.a ); }
Dec 10 2008
prev sibling parent Weed <resume755 mail.ru> writes:
Jarrett Billingsley :
 On Wed, Dec 10, 2008 at 5:31 PM, Weed <resume755 mail.ru> wrote:
 code:

 import std.stdio;

 class MyClass
 {
    invariant uint a = 0;
 }

 void main()
 {
    static MyClass c = new MyClass;
    writeln( c.a );
 }

It's not the class member that wants static initialization, it's your variable declaration. static MyClass c = new MyClass; This is illegal because static variables must be initialized with compile-time constants. The simple way around this is: static MyClass c; // defaults to null c = new MyClass; Which separates the declaration from initialization.

In C++ analogous construction means creation of uninitialized static pointer (in compile time) and it's initialization at first execution of this line in the function. Why D does not behave that way on this construction?
Dec 10 2008
prev sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Thu, 11 Dec 2008 02:13:58 +0300, Weed <resume755 mail.ru> wrote:

 Denis Koroskin пишет:
 On Thu, 11 Dec 2008 01:31:32 +0300, Weed <resume755 mail.ru> wrote:

 But my class does not contain data that need initialization and can be  
 created
 in compile time

 code:

 import std.stdio;

 class MyClass
 {
     invariant uint a = 0;
 }

 void main()
 {
     static MyClass c = new MyClass;
     writeln( c.a );
 }


In C++ analogous construction means creation of uninitialized static pointer (in compile time) and it's initialization at first execution this line in the function. Why D does not behave that way on this construction?

You can this easily yourself. // That's what C++ do under the hood: static MyClass c = null; if (c is null) { c = new MyClass(); } But it is a) thread-unsafe b) a runtime check is done upon every function execution It can be replaced with a more sophisticated (and error prone) solution: static MyClass c = null; if ( (auto old = c) is null ) { MyClass tmp = new MyClass(); if (!CAS(&c, old, tmp)) { delete tmp; } } While it is (arguably) safe, two object might co-exist for a short amount of time, which is unacceptable in many case. As a summary, the C++ solution is full of problems and leads to bad design practices. The D way is to avoid them. You should use a private global variable that is initialized in a static initializer (static this) or a plain old struct, instead.
Dec 10 2008