www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - what's the scope of a static variable inside a local function?

reply Marc <jckj33 gmail.com> writes:
 void foo() {
 	void baa() {
 		static int n;
 		writeln(n++);
 	}
 }
 void main() {
  static int x;
  foo();
  doSomething(x);
 }
does x and n has same lifetime, i.e, program's execution or n is longer available onde foo() call reach out of scope?
Jan 05 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 1/5/18 4:44 PM, Marc wrote:
 void foo() {
     void baa() {
         static int n;
         writeln(n++);
     }
 }
 void main() {
  static int x;
  foo();
  doSomething(x);
 }
does x and n has same lifetime, i.e, program's execution or n is longer available onde foo() call reach out of scope?
Both are the same. The lifetime is actually thread-local (one instance per thread). -Steve
Jan 05 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, January 05, 2018 16:59:38 Steven Schveighoffer via Digitalmars-d-
learn wrote:
 On 1/5/18 4:44 PM, Marc wrote:
 void foo() {
     void baa() {
         static int n;
         writeln(n++);
     }
 }

 void main() {
  static int x;
  foo();
  doSomething(x);
 }
does x and n has same lifetime, i.e, program's execution or n is longer available onde foo() call reach out of scope?
Both are the same. The lifetime is actually thread-local (one instance per thread).
Yeah, they're initialized at compile-time (unlike what you get in C++), which means that you don't get all of that stuff about them being created when the function is first called. And they live as long as the thread lives. What I started wondering about when I saw this though was when the destructors for local static variables get run, and it turns out that they don't. This code ------------------- import std.stdio; struct S { this(string foo) { _foo = foo; } ~this() { writefln("%s destroyed", _foo); } string _foo; } void main() { static mainStatic = S("main"); auto s = S("local"); f(); } void f() { static fStatic = S("f"); } ------------------- prints out local destroyed but doesn't print out anything about main or f. I don't know if that's a bug or not, since the only way that I can think of to make it work would be to have the compiler invisibly add a static destructor to the module to clean them up, and that would cause other problems. It's just not something that I've ever thought about before. - Jonathan M Davis
Jan 05 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 1/5/18 5:07 PM, Jonathan M Davis wrote:

 but doesn't print out anything about main or f. I don't know if that's a bug
 or not, since the only way that I can think of to make it work would be to
 have the compiler invisibly add a static destructor to the module to clean
 them up, and that would cause other problems. It's just not something that
 I've ever thought about before.
Hm... if you counted on thread termination to clean up a resource, then it's definitely a bug. Static dtors would be the most effective way to clean it up, as the mechanism already exists, but they would have to be marked as independent. And of course, -betterC couldn't do it, which means RAII would be broken when compiled that way. -Steve
Jan 05 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, January 05, 2018 17:17:47 Steven Schveighoffer via Digitalmars-d-
learn wrote:
 On 1/5/18 5:07 PM, Jonathan M Davis wrote:
 but doesn't print out anything about main or f. I don't know if that's a
 bug or not, since the only way that I can think of to make it work
 would be to have the compiler invisibly add a static destructor to the
 module to clean them up, and that would cause other problems. It's just
 not something that I've ever thought about before.
Hm... if you counted on thread termination to clean up a resource, then it's definitely a bug. Static dtors would be the most effective way to clean it up, as the mechanism already exists, but they would have to be marked as independent. And of course, -betterC couldn't do it, which means RAII would be broken when compiled that way.
Yeah, so I don't know. Digging around on bugzilla though, it looks like a similar problem was already reported for module-level variables, and Andrei commented that it didn't work with static variables either but wasn't sure what the spec said on the matter: https://issues.dlang.org/show_bug.cgi?id=14650 - Jonathan M Davis
Jan 05 2018