Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Static member vs global variable

3 views
Skip to first unread message

Suneel VLN

unread,
Feb 3, 2010, 12:02:03 AM2/3/10
to
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.

Rolf Magnus

unread,
Feb 3, 2010, 1:00:34 AM2/3/10
to
Suneel VLN wrote:

> 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.

Suneel VLN

unread,
Feb 3, 2010, 1:27:34 AM2/3/10
to

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.

tonydee

unread,
Feb 3, 2010, 1:43:09 AM2/3/10
to

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

Suneel VLN

unread,
Feb 3, 2010, 4:50:26 AM2/3/10
to

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.

Thomas J. Gritzan

unread,
Feb 3, 2010, 11:59:01 AM2/3/10
to
Am 03.02.2010 07:27, schrieb Suneel VLN:
> On Feb 3, 11:00 am, Rolf Magnus <ramag...@t-online.de> wrote:
>> Suneel VLN wrote:
>>> #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;

> 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.

>> 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?

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 ]

--
Thomas

Suneel VLN

unread,
Feb 3, 2010, 12:38:15 PM2/3/10
to
On Feb 3, 9:59 pm, "Thomas J. Gritzan" <phygon_antis...@gmx.de> wrote:
> Am 03.02.2010 07:27, schrieb Suneel VLN:
>
>
>
>
>
> > On Feb 3, 11:00 am, Rolf Magnus <ramag...@t-online.de> wrote:
> >> Suneel VLN wrote:
> >>> #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;
> > 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.
>
> >> 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?
>
> 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 ]
>
> --
> Thomas

Thanks Thomas. I am clear now.

Thanks,
-Suneel VLN.

James Kanze

unread,
Feb 3, 2010, 3:45:03 PM2/3/10
to
On Feb 3, 6:43 am, tonydee <tony_in_da...@yahoo.co.uk> wrote:
> On Feb 3, 3:27 pm, Suneel VLN <suneelsuns...@gmail.com> wrote:

> > On Feb 3, 11:00 am, Rolf Magnus <ramag...@t-online.de> wrote:
> > > 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?

> 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.

--
James Kanze

tonydee

unread,
Feb 3, 2010, 8:51:59 PM2/3/10
to
> On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:
> > On Feb 3, 3:27 pm, Suneel VLN <suneelsuns...@gmail.com> wrote:
> > > On Feb 3, 11:00 am, Rolf Magnus <ramag...@t-online.de> wrote:
> > > > 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?
> > I don't think the Standard guarantees that...
> It does, and several frequently used programming idioms depend
on it.

Thanks for the correction. Sorry for the misinformation.

On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:
> On Feb 3, 6:43 am, tonydee <tony_in_da...@yahoo.co.uk> wrote:
> > 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.

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.

> > That would seem more efficient - why initialise something
> > twice?

> On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:
> 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.

> On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:
> 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

James Kanze

unread,
Feb 4, 2010, 5:26:46 PM2/4/10
to
On Feb 4, 1:51 am, tonydee <tony_in_da...@yahoo.co.uk> wrote:
> > On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:
> On Feb 4, 5:45 am, James Kanze <james.ka...@gmail.com> wrote:

> > On Feb 3, 6:43 am, tonydee <tony_in_da...@yahoo.co.uk> wrote:
> > > 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.

> 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.

--
James Kanze

0 new messages