www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static variables for non-constant expressions?

reply Andrej Mitrovic <none none.none> writes:
I was wondering why static variables can't have a run-time initializer.

For example this won't compile:
void foo(int input)
{
    static x = input;
}

But you can do it manually:
void bar(int input)
{
    static bool initted;
    static typeof(input) x;
    if (!initted) { x = input; initted = true; }
}

It's quite a bit more ugly. You also have to expand this for every new static
variable that you write.

I don't know the background of how static variables really work, so is there a
good reason why the first function can't work like the one below it?
Apr 10 2011
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
 I was wondering why static variables can't have a run-time initializer.
 
 For example this won't compile:
 void foo(int input)
 {
     static x = input;
 }
 
 But you can do it manually:
 void bar(int input)
 {
     static bool initted;
     static typeof(input) x;
     if (!initted) { x = input; initted = true; }
 }
 
 It's quite a bit more ugly. You also have to expand this for every new
 static variable that you write.
 
 I don't know the background of how static variables really work, so is
 there a good reason why the first function can't work like the one below
 it?

They have to be calculated at compile time so that ordering doesn't matter. If the order mattered, then you get into dependency problems or risk using undefined variables. Languages like C++ and Java have problems with that. By forcing all module level variables, member variables, and static variables (be they class variables or local variables) to have their initializers be static, it avoids the order problem completely. In all cases except for local static variables, you can use the appropriate constructor if you need to do the initialization at runtime. For static local variables, you'd have to use another static local variable which indicated whether the first had been initialized yet or not. In any case, by forcing all variables other than non-static local variables to have their direct initializers be determined at compile time avoids dependency problems which often result in undefined behavior in other languages. - Jonathan M Davis
Apr 10 2011
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
On 11/04/2011 02:37, Jonathan M Davis wrote:
<snip>
 I don't know the background of how static variables really work, so is
 there a good reason why the first function can't work like the one below
 it?

They have to be calculated at compile time so that ordering doesn't matter. If the order mattered, then you get into dependency problems or risk using undefined variables. Languages like C++ and Java have problems with that.

I recall reading that in C++, static variables are initialised on first call. Which would have to mean that it does something like that internally. But I might be imagining it. I'll have to experiment. Can you give an example of the dependency problems this might lead to? Stewart.
Apr 11 2011
parent reply Simon <s.d.hammett gmail.com> writes:
On 11/04/2011 22:15, Stewart Gordon wrote:
 On 11/04/2011 02:37, Jonathan M Davis wrote:
 <snip>
 I don't know the background of how static variables really work, so is
 there a good reason why the first function can't work like the one below
 it?

They have to be calculated at compile time so that ordering doesn't matter. If the order mattered, then you get into dependency problems or risk using undefined variables. Languages like C++ and Java have problems with that.

I recall reading that in C++, static variables are initialised on first call. Which would have to mean that it does something like that internally. But I might be imagining it. I'll have to experiment. Can you give an example of the dependency problems this might lead to? Stewart.

In visual C++ all static vars with assignments/constructors get initialised by the CRT before main starts, though in an undefined order. Can lead to bugs if you use them carelessly. Pretty sure that applies to other compilers as well. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Apr 11 2011
parent reply Steven Wawryk <stevenw acres.com.au> writes:
On 12/04/11 07:36, Simon wrote:
 On 11/04/2011 22:15, Stewart Gordon wrote:
 On 11/04/2011 02:37, Jonathan M Davis wrote:
 <snip>
 I don't know the background of how static variables really work, so is
 there a good reason why the first function can't work like the one
 below
 it?

They have to be calculated at compile time so that ordering doesn't matter. If the order mattered, then you get into dependency problems or risk using undefined variables. Languages like C++ and Java have problems with that.

I recall reading that in C++, static variables are initialised on first call. Which would have to mean that it does something like that internally. But I might be imagining it. I'll have to experiment. Can you give an example of the dependency problems this might lead to? Stewart.

In visual C++ all static vars with assignments/constructors get initialised by the CRT before main starts, though in an undefined order. Can lead to bugs if you use them carelessly. Pretty sure that applies to other compilers as well.

This is true for static "globals" and static members, but the C++ standard requires static locals (local to functions) to be initialized on first call. It's a widely used idiom to avoid static initialization order issues to use functions that do nothing more than return a reference to a static local rather than use static globals directly.
Apr 11 2011
parent Simon <s.d.hammett gmail.com> writes:
On 12/04/2011 01:59, Steven Wawryk wrote:
 On 12/04/11 07:36, Simon wrote:
 On 11/04/2011 22:15, Stewart Gordon wrote:
 On 11/04/2011 02:37, Jonathan M Davis wrote:


This is true for static "globals" and static members, but the C++ standard requires static locals (local to functions) to be initialized on first call. It's a widely used idiom to avoid static initialization order issues to use functions that do nothing more than return a reference to a static local rather than use static globals directly.

Hmm, that's only true for objects w/ ctors by the looks of it. The OPs question was about int, though values types can just be compiled in. MS must have changed their compiler to match the spec then at some point; I've been bitten by undefined order of statics before. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Apr 12 2011