www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - local class instance (at module-level)

reply spir <denis.spir gmail.com> writes:
I desperately try to declare/define/initialise a simple class instance at 
module-level. This is a special (conceptually static and immutable) instance 
used as a "marker", that just should exist and be accessible by methods of this 
class and/or other classes defined in the same module. (Thus I don't care if 
TLS.) I use it as a remplacement for null, to avoid semantic confusion and 
unhelpful segfaults in case of bug.

I have tried a number of options and never manage to do it, including:
* [C/auto/static immutable c0] = new C(0) ;
* C c0 ; c0.i = 0 ;
* defining a static this()
* more...

The most confusing error is:
Error: variable `_base.c0` is a thread-local class and cannot have a static 
initializer. Use `static this()` to initialize instead.

I also could not find any information --for a while, repeatedly, since I can go 
on developing in the meantime, using null instead. I'm bluffed and confused, 
since there is nothing weird in that, is there? (the compiler can just allocate 
it in static mem and take the address)

Reduced test case:
===========================
class C {
     uint i ;
     this (uint i) {
         this.i = i ;
     }
}

// error
auto c0 = new C(0) ;

void main () {
     // ok
     auto c0 = new C(0) ;
}
===========================

I would enjoy an explanation (or a pointer to) in addition to a solution.

Thank you,
diniz

PS: I take the opportnity to ask if I can count on the compiler to intern 
literal strings (which my code may use in several places, including loops),
esp. 
"", or should I declare and use (for instance):
static immutable s0 = "" ;
Mar 14 2019
next sibling parent Andrea Fontana <nospam example.org> writes:
On Thursday, 14 March 2019 at 11:05:22 UTC, spir wrote:

 The most confusing error is:
 Error: variable `_base.c0` is a thread-local class and cannot 
 have a static initializer. Use `static this()` to initialize 
 instead.
Error is reffering to: https://dlang.org/spec/module.html#staticorder You can do this: C c0; static this() { c0 = new C(); } Andrea
Mar 14 2019
prev sibling next sibling parent Alex <sascha.orlov gmail.com> writes:
On Thursday, 14 March 2019 at 11:05:22 UTC, spir wrote:
 I desperately try to declare/define/initialise a simple class 
 instance at module-level. This is a special (conceptually 
 static and immutable) instance used as a "marker", that just 
 should exist and be accessible by methods of this class and/or 
 other classes defined in the same module. (Thus I don't care if 
 TLS.) I use it as a remplacement for null, to avoid semantic 
 confusion and unhelpful segfaults in case of bug.

 I have tried a number of options and never manage to do it, 
 including:
 * [C/auto/static immutable c0] = new C(0) ;
 * C c0 ; c0.i = 0 ;
 * defining a static this()
 * more...

 The most confusing error is:
 Error: variable `_base.c0` is a thread-local class and cannot 
 have a static initializer. Use `static this()` to initialize 
 instead.

 I also could not find any information --for a while, 
 repeatedly, since I can go on developing in the meantime, using 
 null instead. I'm bluffed and confused, since there is nothing 
 weird in that, is there? (the compiler can just allocate it in 
 static mem and take the address)

 Reduced test case:
 ===========================
 class C {
     uint i ;
     this (uint i) {
         this.i = i ;
     }
 }

 // error
 auto c0 = new C(0) ;

 void main () {
     // ok
     auto c0 = new C(0) ;
 }
 ===========================

 I would enjoy an explanation (or a pointer to) in addition to a 
 solution.

 Thank you,
 diniz

 PS: I take the opportnity to ask if I can count on the compiler 
 to intern literal strings (which my code may use in several 
 places, including loops), esp. "", or should I declare and use 
 (for instance):
 static immutable s0 = "" ;
Basically, this works for me: ´´´ class C { uint i ; this (uint i) { this.i = i ; } } C c0; static this() { c0 = new C(0); } void main () { assert(!(c0 is null)); } ´´´
Mar 14 2019
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2019-03-14 12:05, spir wrote:
 I desperately try to declare/define/initialise a simple class instance 
 at module-level. This is a special (conceptually static and immutable) 
 instance used as a "marker", that just should exist and be accessible by 
 methods of this class and/or other classes defined in the same module. 
 (Thus I don't care if TLS.) I use it as a remplacement for null, to 
 avoid semantic confusion and unhelpful segfaults in case of bug.
 
 I have tried a number of options and never manage to do it, including:
 * [C/auto/static immutable c0] = new C(0) ;
 * C c0 ; c0.i = 0 ;
 * defining a static this()
 * more...
 
 The most confusing error is:
 Error: variable `_base.c0` is a thread-local class and cannot have a 
 static initializer. Use `static this()` to initialize instead.
 
 I also could not find any information --for a while, repeatedly, since I 
 can go on developing in the meantime, using null instead. I'm bluffed 
 and confused, since there is nothing weird in that, is there? (the 
 compiler can just allocate it in static mem and take the address)
 
 Reduced test case:
 ===========================
 class C {
      uint i ;
      this (uint i) {
          this.i = i ;
      }
 }
 
 // error
 auto c0 = new C(0) ;
 
 void main () {
      // ok
      auto c0 = new C(0) ;
 }
 ===========================
 
 I would enjoy an explanation (or a pointer to) in addition to a solution.
 
It works if it's not a TLS variable: class C { uint i ; this (uint i) { this.i = i ; } this (uint i) shared { this.i = i ; } this (uint i) immutable { this.i = i ; } } __gshared c0 = new C(0); shared c1 = new shared C(1); immutable c2 = new immutable C(2); You only need one of the constructors depending on if you want a __gshared, shared or immutable variable.
 PS: I take the opportnity to ask if I can count on the compiler to 
 intern literal strings (which my code may use in several places, 
 including loops), esp. "", or should I declare and use (for instance):
 static immutable s0 = "" ;
String literals are stored in the executable. Each unique string literal is only stored once. -- /Jacob Carlborg
Mar 14 2019
parent reply ag0aep6g <anonymous example.com> writes:
On 14.03.19 20:43, Jacob Carlborg wrote:
 class C {
      uint i ;
      this (uint i) {
          this.i = i ;
      }
 
      this (uint i) shared {
          this.i = i ;
      }
 
      this (uint i) immutable {
          this.i = i ;
      }
 }
 
 __gshared c0 = new C(0);
 shared c1 = new shared C(1);
 immutable c2 = new immutable C(2);
 
 You only need one of the constructors depending on if you want a 
 __gshared, shared or immutable variable.
If you make it `pure`, you can use the same constructor in all cases: ---- class C { uint i ; this (uint i) pure { this.i = i ; } } __gshared c0 = new C(0); shared c1 = new shared C(1); immutable c2 = new immutable C(2); ----
Mar 14 2019
parent spir <denis.spir gmail.com> writes:
On 15/03/2019 00:45, ag0aep6g via Digitalmars-d-learn wrote:
 On 14.03.19 20:43, Jacob Carlborg wrote:
 class C {
      uint i ;
      this (uint i) {
          this.i = i ;
      }

      this (uint i) shared {
          this.i = i ;
      }

      this (uint i) immutable {
          this.i = i ;
      }
 }

 __gshared c0 = new C(0);
 shared c1 = new shared C(1);
 immutable c2 = new immutable C(2);

 You only need one of the constructors depending on if you want a __gshared, 
 shared or immutable variable.
If you make it `pure`, you can use the same constructor in all cases: ---- class C {     uint i ;     this (uint i) pure {         this.i = i ;     } } __gshared c0 = new C(0); shared c1 = new shared C(1); immutable c2 = new immutable C(2); ----
all right, thank you!
Mar 14 2019