Thread overview
what's the scope of a static variable inside a local function?
Jan 05, 2018
Marc
Jan 05, 2018
Jonathan M Davis
Jan 06, 2018
Jonathan M Davis
January 05, 2018
> 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?

January 05, 2018
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
January 05, 2018
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

January 05, 2018
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
January 05, 2018
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