By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,260 Members | 1,233 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,260 IT Pros & Developers. It's quick & easy.

Intialisation order and statics

P: n/a
Since it says in the standard that the order of initialization of
variables is indeterminate, does this also apply to a static within a
function?

e.g.

int GetInt()
{
static int test = 458;
return test;
}
when might test be initialized? Is it indeterminate like any other
object. In other words calling GetInt() before main() is executed
doesn't guarantee test has been initialized?

If this is the case how does one avoid problems with static
initialisation. For instance if I have a class A

class A
{
MyMutex mutex;
};

A a_object;

Here, let us say that MyMutex's constructor will read a static member
variable within the MyMutex class. Presumably, this is undefined
behavior since the static variable may not yet have been initialised.

If that is the case how do you avoid this sort of trap?
Jul 23 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a

"Spacen Jasset" <sp**********@yahoo.co.uk> skrev i en meddelelse
news:41******@x-privat.org...
Since it says in the standard that the order of initialization of
variables is indeterminate, does this also apply to a static within a
function?

e.g.

int GetInt()
{
static int test = 458;
return test;
}
when might test be initialized? Is it indeterminate like any other object.
In other words calling GetInt() before main() is executed doesn't
guarantee test has been initialized?


Calling GetInt assures that test will be initialised, thus you'll have no
problems. In your case, test will be initialised automatically, but if you
had a more complicated element (such as a mutex), the element will be
initialised the first time you call the function.

/Peter
[snip]
Jul 23 '05 #2

P: n/a
Peter Koch Larsen wrote:
"Spacen Jasset" <sp**********@yahoo.co.uk> skrev i en meddelelse
news:41******@x-privat.org...
Since it says in the standard that the order of initialization of
variables is indeterminate, does this also apply to a static within a
function?

e.g.

int GetInt()
{
static int test = 458;
return test;
}
when might test be initialized? Is it indeterminate like any other object.
In other words calling GetInt() before main() is executed doesn't
guarantee test has been initialized?

Calling GetInt assures that test will be initialised, thus you'll have no
problems. In your case, test will be initialised automatically, but if you
had a more complicated element (such as a mutex), the element will be
initialised the first time you call the function.


which has always been a puzzle to me concerning efficiency. Does it mean
that at runtime there is a test in the function to see if the variable
is initialized? In other word, is the code:
void foo()
{
static int n = 4;
//
// ...
//
}
equivalent (once compiled) to the code:
static bool foo_run = false;
void foo()
{
static int n;
if (!foo_run) { n=4;foo_run=true; }
//
// ...
//
}

If it is the case, then using static inside function (which I thought a
good practice for it declares things closer to where it is needed) incur
a potentially huge cost!!!

Otherwise, I don't see how the generated compiled code can do without a
dynamic test?!? Oh yes, it could change the pointer function of foo so
the first time it points to the initialization of n and the second time
to a couple instructions further! Is that true?
/Peter
[snip]

Jul 23 '05 #3

P: n/a

Xavier Décoret wrote:

[ function statics ]
which has always been a puzzle to me concerning efficiency. Does it mean that at runtime there is a test in the function to see if the variable is initialized? In other word, is the code:
Probably, for complex cases.
void foo()
{
static int n = 4;
//
// ...
//
}
equivalent (once compiled) to the code:
static bool foo_run = false;
void foo()
{
static int n;
if (!foo_run) { n=4;foo_run=true; }
//
// ...
//
}

If it is the case, then using static inside function (which I thought a good practice for it declares things closer to where it is needed) incur a potentially huge cost!!!
Not as bad as you'd think. Modern CPUs use branch prediction, and they
tend to do quite well on such biased tests. Some compilers can even
tell the CPU that the branch is likely false, and only the first call
will be slower - but you typically don't care about that case, since
your initialization makes the function slower.
Otherwise, I don't see how the generated compiled code can do without a dynamic test?!? Oh yes, it could change the pointer function of foo so the first time it points to the initialization of n and the second time to a couple instructions further! Is that true?


One of the most obvious ways is to initialize n at program startup. In
general, you can detect the ctor call if you're initializing a static
class-type object. There's no way to see the initial value of static
int n, so it may be initialized from the startup code along with the
globals.

Another way could be to use page faults on CPUs that support them.
Don't allocate RAM for the static variable, trap the page fault and
initialize the variable just-in-time (before the first read). In a
modern OS the CPU has to do this test anyway, to deal with virtual
memory.

A similar solution is to place the code (not the data) in paged-out
memory, and use the same trap to initialize the variable on the first
call of the funtion.

Regards,
Michiel Salters

Jul 23 '05 #4

P: n/a
Peter Koch Larsen wrote:
"Spacen Jasset" <sp**********@yahoo.co.uk> skrev i en meddelelse .... Calling GetInt assures that test will be initialised, thus you'll have no
problems. In your case, test will be initialised automatically, but if you
had a more complicated element (such as a mutex), the element will be
initialised the first time you call the function.

/Peter
[snip]

I see that. But what if GetInt() istself is called before main() starts
to run. I.e. by something like this:
int myint = GetInt();

could test be uninitiaised at this point. In most cases it will be since
the linker will most likly put myint in an initialised data segment.
However, that isn't possible for a class object since it's constructor
must be called. I don't see anything explicit in the standard that says
static variables inside always get initialised when they are called.
Jul 23 '05 #5

P: n/a

Spacen Jasset wrote:
....
I see that. But what if GetInt() istself is called before main() starts to run. I.e. by something like this:
int myint = GetInt();

could test be uninitiaised at this point. In most cases it will be since the linker will most likly put myint in an initialised data segment.
However, that isn't possible for a class object since it's constructor must be called. I don't see anything explicit in the standard that says static variables inside always get initialised when they are called.


6.7/4 states that
"A local object of POD type (3.9) with static storage duration
initialized
with constant-expressions is initialized before its block is first
entered."
( that covers your example of a static int )

"An implementation is permitted to perform early initialization of
other
local objects with static storage duration under the same conditions
that
an implementation is permitted to statically initialize an object with
static storage duration in namespace scope (3.6.2). Otherwise such an
object is initialized the first time control passes through its
declaration; such an object is considered initialized upon the
completion
of its initialization."

which covers the more interesting cases of static objects with
constructors that can be observed.

HTH,
Michiel Salters

Jul 23 '05 #6

P: n/a
msalters wrote:
Spacen Jasset wrote:
...
I see that. But what if GetInt() istself is called before main()


starts
to run. I.e. by something like this:
int myint = GetInt();

could test be uninitiaised at this point. In most cases it will be


since
the linker will most likly put myint in an initialised data segment.
However, that isn't possible for a class object since it's


constructor
must be called. I don't see anything explicit in the standard that


says
static variables inside always get initialised when they are called.

6.7/4 states that
"A local object of POD type (3.9) with static storage duration
initialized
with constant-expressions is initialized before its block is first
entered."
( that covers your example of a static int )

"An implementation is permitted to perform early initialization of
other
local objects with static storage duration under the same conditions
that
an implementation is permitted to statically initialize an object with
static storage duration in namespace scope (3.6.2). Otherwise such an
object is initialized the first time control passes through its
declaration; such an object is considered initialized upon the
completion
of its initialization."

which covers the more interesting cases of static objects with
constructors that can be observed.

HTH,
Michiel Salters

That's interesting, thanks. The the following is also correct?:
class A
{
public:
GetInt()
{
return myInt;
}
private:
static int myInt;
};
you can't be sure myInt is initialised when GetInt() is called, but you
can if you use a local static variable.

Therefore were have:
Singletons should always be initialised as local static objects within a
funcion to gurantee proper initialisation.

Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Browse more C / C++ Questions on Bytes