Thread overview
static variables for non-constant expressions?
Apr 11, 2011
Andrej Mitrovic
Apr 11, 2011
Jonathan M Davis
Apr 11, 2011
Stewart Gordon
Apr 11, 2011
Simon
Apr 12, 2011
Steven Wawryk
Apr 12, 2011
Simon
April 11, 2011
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?
April 11, 2011
> 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
April 11, 2011
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.
<snip>

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.
April 11, 2011
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.
> <snip>
>
> 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
April 12, 2011
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.
>> <snip>
>>
>> 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.

April 12, 2011
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