Static member vs global variable

S

Suneel VLN

Hi all,

Below example is the from the famous C++ book "Thinking in C++, Vol
1".

#include <iostream>
using namespace std;
int x = 100;

class WithStatic
{
static int x;
static int y;
public:
void print() const
{
cout << "WithStatic::x = " << x << endl;
cout << "WithStatic::y = " << y << endl;
}
};

int WithStatic::y = x + 1;
int WithStatic::x = 51;

int main()
{
WithStatic ws;
ws.print();
}

Output is...

WithStatic::x = 51
WithStatic::y = 52


My questions are...

1. Why local x took precedence over global x?
2. Even though local x initialized after local y initialization, how x
value updated when initializing y?

Can anybody explain me this behavior?

Thanks in advance.
--Suneel VLN.
 
R

Rolf Magnus

Suneel said:
Hi all,

Below example is the from the famous C++ book "Thinking in C++, Vol
1".

#include <iostream>
using namespace std;
int x = 100;

class WithStatic
{
static int x;
static int y;
public:
void print() const
{
cout << "WithStatic::x = " << x << endl;
cout << "WithStatic::y = " << y << endl;
}
};

int WithStatic::y = x + 1;
int WithStatic::x = 51;

int main()
{
WithStatic ws;
ws.print();
}

Output is...

WithStatic::x = 51
WithStatic::y = 52


My questions are...

1. Why local x took precedence over global x?

Because that's how the standard defines it. The variable in the closest
scope is used.
BTW: I wouldn't call it "local". That term is normally used for variables
defined within a function.
2. Even though local x initialized after local y initialization, how x
value updated when initializing y?

For objects with static storage duration, there are two types of
initialization, static and dynamic. static initialization is done before
dynamic initialization, and if a constant expression is used for an object
of POD type, the initialzation is static. 51 is a constant expression, so x
is initialized statically, while x + 1 is not a constant expression, so y is
initialized dynamically.
 
S

Suneel VLN

Because that's how the standard defines it. The variable in the closest
scope is used.
BTW:  I wouldn't call it "local". That term is normally used for variables
defined within a function.


For objects with static storage duration, there are two types of
initialization, static and dynamic. static initialization is done before
dynamic initialization, and if a constant expression is used for an object
of POD type, the initialzation is static. 51 is a constant expression, so x
is initialized statically, while x + 1 is not a constant expression, so y is
initialized dynamically.

I am little bit confused with this statement...
Because that's how the standard defines it. The variable in the closest
scope is used.

static x is a private member inside a class. How come it was in
closest scope at that line?
For objects with static storage duration, there are two types of
initialization, static and dynamic. static initialization is done before
dynamic initialization

in such case during static initialization will y be initialized to 0?

Thanks,
--Suneel VLN.
 
T

tonydee

in such case during static initialization will y be initialized to 0?

I don't think the Standard guarantees that... my recollection is
compilers are free to use uninitialised/reclaimed memory for static
variables that are to be dynamically initialised. That would seem
more efficient - why initialise something twice?

Cheers,
Tony
 
S

Suneel VLN

I don't think the Standard guarantees that... my recollection is
compilers are free to use uninitialised/reclaimed memory for static
variables that are to be dynamically initialised.  That would seem
more efficient - why initialise something twice?

Cheers,
Tony

OK. If that is the case, then x will be initialized statically during
program loading and y will be initialized dynamically during program
execution.

Could anybody answer my other question...
static x is a private member inside a class. How come it was in
closest scope at that line?

Thanks,
--Suneel VLN.
 
T

Thomas J. Gritzan

Am 03.02.2010 07:27, schrieb Suneel VLN:
static x is a private member inside a class. How come it was in
closest scope at that line?

The standard says (§8.5/12, current draft N3000):
"An initializer for a static member is in the scope of the member’s class."

Access levels and visibility are two different concepts. The compiler
first decides which variable or function is used, depending on scope and
-- when the function is overloaded -- the types of the parameters. After
that, the compiler checks if the code has the right to access this
variable or function.
in such case during static initialization will y be initialized to 0?

Yes. For variables with static storage duration and dynamic
initialization, the initialization is a two step process. They are
zero-initialized before any user written code runs.

From the standard (§8.5/9):
[ Note: Every object of static storage duration is zero-initialized at
program startup before any other initialization
takes place. In some cases, additional initialization is done later.
—end note ]
 
S

Suneel VLN

Am 03.02.2010 07:27, schrieb Suneel VLN:




static x is a private member inside a class. How come it was in
closest scope at that line?

The standard says (§8.5/12, current draft N3000):
"An initializer for a static member is in the scope of the member’s class."

Access levels and visibility are two different concepts. The compiler
first decides which variable or function is used, depending on scope and
-- when the function is overloaded -- the types of the parameters. After
that, the compiler checks if the code has the right to access this
variable or function.
in such case during static initialization will y be initialized to 0?

Yes. For variables with static storage duration and dynamic
initialization, the initialization is a two step process. They are
zero-initialized before any user written code runs.

From the standard (§8.5/9):
[ Note: Every object of static storage duration is zero-initialized at
program startup before any other initialization
takes place. In some cases, additional initialization is done later.
—end note ]

Thanks Thomas. I am clear now.

Thanks,
-Suneel VLN.
 
J

James Kanze

I don't think the Standard guarantees that...

It does, and several frequently used programming idioms depend
on it.
my recollection is compilers are free to use
uninitialised/reclaimed memory for static variables that are
to be dynamically initialised.

They certainly can't use reclaimed memory, since the object must
be present for the entire lifetime of the program.
That would seem more efficient - why initialise something
twice?

Maybe because the first initialization is for all intents and
purposes free. And because it might be useful to be able to
tell whether an object is initialized or not---objects with
static lifetime are about the only objects which can be accessed
normally before their constructor has run.
 
T

tonydee

It does, and several frequently used programming idioms depend
on it.

Thanks for the correction. Sorry for the misinformation.

They certainly can't use reclaimed memory, since the object must
be present for the entire lifetime of the program.

I was thinking at the level of the OS allocating the memory for the
processes it's loading... the memory is reclaimed from other processes
or system caches and allocated to the loading process. Poor wording
if it's put you in mind of the intra-process heap.
Maybe because the first initialization is for all intents and
purposes free.

memset() is pretty fast, and better OSs tend to do it anyway for
security reasons, but acceptable performance is very context
dependent.
 And because it might be useful to be able to
tell whether an object is initialized or not---objects with
static lifetime are about the only objects which can be accessed
normally before their constructor has run.

Very true, and stupid of me for not reasoning from those uses.

Cheers,
Tony
 
J

James Kanze

I was thinking at the level of the OS allocating the memory
for the processes it's loading... the memory is reclaimed from
other processes or system caches and allocated to the loading
process. Poor wording if it's put you in mind of the
intra-process heap.

Yes. The OS certainly does reuse memory that has been freed by
other processes; otherwise, it would run out of memory very
quickly. For security reasons, however, it shouldn't reuse this
memory without overwriting it (although some OS's do). And if
it's reusing it for static memory, the standard requires that
the memory be "zero initialized" somewhere---if the OS doesn't
do it, the kick-off routine in the CTR (the program that calls
main) must.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top