Static losing its value?

S

Steve Edwards

Hi,

I have a class with some static variables:

in MyClass.h
//-------------------------
lass MyClass{
....
public:
static long myVals[4]; // declaration
}
long MyClass:: myVals[4] = {0,0,0,0}; //definition
//----------------------------

Then in another part of my program: (in This.cpp)

MyClass:: myVals[1] = 123;

But then later on when I try to retrieve this: (in That.cpp)

long x = MyClass:: myVals[1] ;

x always equals zero!?


Everything compiles with no errors or warnings, so can anyone point out
why the static is losing its value?

Thanks

Steve
 
A

Alf P. Steinbach

* Steve Edwards:
Hi,

I have a class with some static variables:

in MyClass.h
//-------------------------
lass MyClass{

Just tell me where to send my contribution, and I'll support the
movement to make "lass" a C++ keyword.

...
public:
static long myVals[4]; // declaration
}
long MyClass:: myVals[4] = {0,0,0,0}; //definition

This is the beauty of the 'lass' keyword: you don't need semicolons
where you'd otherwise need them using 'class'.

//----------------------------

Then in another part of my program: (in This.cpp)

MyClass:: myVals[1] = 123;

But then later on when I try to retrieve this: (in That.cpp)

long x = MyClass:: myVals[1] ;

x always equals zero!?

That's a Great Mysterie.

Everything compiles with no errors or warnings, so can anyone point out
why the static is losing its value?

Obviously, it's the lass pulling your strings. Or, take a look at line
666. Now, that's an ominous number, so that's surely where the problem
is located.

If that doesn't help, then try to post a minimal program that exhibits
the problem.

Hth.,

- Alf
 
S

Steve555

OK, I probably asked for that (...even though "no errors or warnings"
would suggest it was a newsgroup-only typo.)

class MyClass{
....
public:
static long myVals[4]; // declaration
};
long MyClass:: myVals[4] = {0,0,0,0}; //definition


Do I take it from the "Mysterie...666" comment that there shouldn't be
a problem and so I must have a mistake elsewhere?

Thanks

Steve
 
J

Jakob Bieling

Steve555 said:
OK, I probably asked for that (...even though "no errors or warnings"
would suggest it was a newsgroup-only typo.)

class MyClass{
...
public:
static long myVals[4]; // declaration
};
long MyClass:: myVals[4] = {0,0,0,0}; //definition


Do I take it from the "Mysterie...666" comment that there shouldn't
be a problem and so I must have a mistake elsewhere?

Well, the problem is, that the code you gave:
Then in another part of my program: (in This.cpp)

MyClass:: myVals[1] = 123;

But then later on when I try to retrieve this: (in That.cpp)

long x = MyClass:: myVals[1] ;

x always equals zero!?

does not show anything about your real setup. Pasting the above
(without obvious text) into a cpp will not compile, thus making us guess
what your code looks like.

By 'post a minimal program that exhibits the problem' Alf told you
to post the *tiniest* possible source (including #include's, main, class
definitions) that still shows the problem. This excludes any defintions,
functions and whatnot, that do not influence the problem.

hth
 
S

Steve555

Apologies, hopefully this will clarify my problem:

----- In Test.h: -----
class Test
{
public:
Test(){};
virtual ~Test(){};
static long myVal;
};
long Test::myVal;

----- In main.cpp: -----
#include "Test.h"
#include "GetVal.h"
int main(int argc, const char *argv[])
{
Test::myVal = 17;
GetVal();
}

----- In GetVal.cpp -----
#include "Test.h"
#include "GetVal.h"
void GetVal()
{
long x = Test::myVal;
}

----- In GetVal.h -----
void GetVal();


The problem is that when GetVal() is called, x =0

In case it isn't obvious, I'm trying to create a 'global' type of
variable called myVal as part of the class Test, which maintains its
value, wherever it is accessed.
(I'm porting some old C code and trying to tidy globals in to statics.)

Thanks

Steve
 
J

Jakob Bieling

Steve555 said:
Apologies, hopefully this will clarify my problem:

----- In Test.h: -----
class Test
{
public:
Test(){};
virtual ~Test(){};
static long myVal;
};
long Test::myVal;

The above line should go into one compilation unit only. Actually, I
wonder why you did not get a linker error when linking main.cpp and
GetVal.cpp, because they both include Test.h and thus also both define
Test::myVal.
----- In main.cpp: -----
#include "Test.h"
#include "GetVal.h"
int main(int argc, const char *argv[])
{
Test::myVal = 17;
GetVal();
}

----- In GetVal.cpp -----
#include "Test.h"
#include "GetVal.h"

You could insert it here, for example:

long Test::myVal;
void GetVal()
{
long x = Test::myVal;
}

----- In GetVal.h -----
void GetVal();


The problem is that when GetVal() is called, x =0

Should be solved now.

regards
 
T

Thomas Tutone

Steve555 said:
Apologies, hopefully this will clarify my problem:

----- In Test.h: -----
class Test
{
public:
Test(){};
virtual ~Test(){};
static long myVal;
};
long Test::myVal;

The above line needs to be in a .cpp file, not in a header file. It
should only appear once in the entire code, not in every translation
unit that includes Test.h. That may be the source of your problem.
I'm surprised you didn't get a linker error when you compiled and
linked.
----- In main.cpp: -----
#include "Test.h"
#include "GetVal.h"
int main(int argc, const char *argv[])
{
Test::myVal = 17;
GetVal();
}

----- In GetVal.cpp -----
#include "Test.h"
#include "GetVal.h"
void GetVal()
{
long x = Test::myVal;
}

----- In GetVal.h -----
void GetVal();


The problem is that when GetVal() is called, x =0

Uhhhmmm... How do you know? Both Alf and Jakob asks you to post the
tiniest possible source that shows the problem. How, exactly, does
this show the problem?

Also, please include some context when you reply to a message. Most
people don't use google groups, so they may not be able to figure out
that your most recent posting relates to the prior posts.

Best regards,

Tom
 
S

Steve555

Apologies, hopefully this will clarify my problem:
----- In Test.h: -----
class Test
{
public:
Test(){};
virtual ~Test(){};
static long myVal;
};
long Test::myVal;


The above line should go into one compilation unit only. Actually,
I
wonder why you did not get a linker error when linking main.cpp and
GetVal.cpp, because they both include Test.h and thus also both define
Test::myVal.
----- In main.cpp: -----
#include "Test.h"
#include "GetVal.h"
int main(int argc, const char *argv[])
{
Test::myVal = 17;
GetVal();
}
----- In GetVal.cpp -----
#include "Test.h"
#include "GetVal.h"


You could insert it here, for example:
long Test::myVal;
void GetVal()
{
long x = Test::myVal;
}
----- In GetVal.h -----
void GetVal();
The problem is that when GetVal() is called, x =0


Should be solved now.

Many thanks, Jakob, fixed it.
 
S

Steve555

How, exactly, does this show the problem?
How does posting a complete tiny program satisfy being asked to post a
complete tiny program??
No, sorry, you'll have to run that one by me again!
Also, please include some context when you reply to a message.

Noted.

Thanks
Steve
 
T

Thomas Tutone

Steve555 said:
How does posting a complete tiny program satisfy being asked to post a
complete tiny program??
No, sorry, you'll have to run that one by me again!


Noted.

<SIGH>

Steve, you left out the context that answers your own question.

What I wrote was:

"Uhhhmmm... How do you know? Both Alf and Jakob asks you to post the
tiniest possible source that shows the problem. How, exactly, does
this show the problem? "

Your response was:

"How does posting a complete tiny program satisfy being asked to post a
complete tiny program??"

That's a non-sequitur. I wasn't taking issue that the program you
posted was sufficiently small - it was, and thank you for making it
small. I was pointing out that it didn't show the problem. There was
nothing showing that that the value of x was zero - we just had you
telling us that it was, but how did you know? Were you running the
program under a debugger? What I was trying to subtly point out - I
guess too subtly - is that the program you post needs to show the
error. Traditionally, one does that either by sending the apparently
wrong value to std::cout so we can see it, or by including an assert.
In other words, you post a program and say "I was expecting the output
to be [whatever], but when I compile and run it, instead the output is
[whatever]. Please help me understand why."

Anyway, I'm glad your problem was solved.

Best regards,

Tom
 
S

Steve555

Steve555 said:
How does posting a complete tiny program satisfy being asked to post a
complete tiny program??
No, sorry, you'll have to run that one by me again!


<SIGH>
Steve, you left out the context that answers your own question.

What I wrote was:

"Uhhhmmm... How do you know? Both Alf and Jakob asks you to post the
tiniest possible source that shows the problem. How, exactly, does
this show the problem? "

Your response was:

"How does posting a complete tiny program satisfy being asked to post a

complete tiny program??"

That's a non-sequitur. I wasn't taking issue that the program you
posted was sufficiently small - it was, and thank you for making it
small. I was pointing out that it didn't show the problem. There was
nothing showing that that the value of x was zero - we just had you
telling us that it was, but how did you know? Were you running the
program under a debugger? What I was trying to subtly point out - I
guess too subtly - is that the program you post needs to show the
error. Traditionally, one does that either by sending the apparently
wrong value to std::cout so we can see it, or by including an assert.
In other words, you post a program and say "I was expecting the output
to be [whatever], but when I compile and run it, instead the output is
[whatever]. Please help me understand why."

Anyway, I'm glad your problem was solved.

========================================================

Tom,

First of all, I apologise for that mildly sarcastic tone. I didn't
understand from your question what you thought was lacking, so to me it
wasn't a non-sequitur. However, I understand now from your explanation,
and thank you for having the patience.
To answer your other question:
There was
nothing showing that that the value of x was zero - we just had you
telling us that it was, but how did you know?

Well, in the snippet below, it shows that GetVal() is called from main,
and so I could not fail to see x assigned a value, once I hit it in the
debugger: ( ... er, but as you say, I forgot to mention I was running
the debugger!)
----- In main.cpp: -----
#include "Test.h"
#include "GetVal.h"
int main(int argc, const char *argv[])
{
Test::myVal = 17;
GetVal();
}
void GetVal()
{
long x = Test::myVal;
}


(1. As I'm clearly floundering with my newsgroup technique, too, I
should point out that I'm not questioning any advice kindly given, just
that I don't fully understand some point.
2. I'm trying to post from Google, and it doesn't appear to do quoting,
so apologies for the ugliness of the manually cut'n'pasted bits)

Many thanks

Steve
 
T

Thomas Tutone

Steve555 said:
Tom,

First of all, I apologise for that mildly sarcastic tone. I didn't
understand from your question what you thought was lacking, so to me it
wasn't a non-sequitur. However, I understand now from your explanation,
and thank you for having the patience.
To answer your other question:

Well, in the snippet below, it shows that GetVal() is called from main,
and so I could not fail to see x assigned a value, once I hit it in the
debugger: ( ... er, but as you say, I forgot to mention I was running
the debugger!)

Thanks, Steve - I probably should have figured that out. Many of the
people posting questions here don't know how to use a debugger, but I
shouldn't have assumed you fell into that category.
2. I'm trying to post from Google, and it doesn't appear to do quoting,
so apologies for the ugliness of the manually cut'n'pasted bits)

Right, you've fallen into the google groups bug/feature trap. To reply
with context using google, click on "show options," and then "Reply,"
rather than initially clicking on "Reply" at the bottom of the message.
It's not clear why google refuses to correct that problem - perhaps to
limit excessive quoting.

Anyway, thanks for taking the time to respond to my slightly pedantic
criticism - your courtesy is appreciated.

Best regards,

Tom
 
R

Richard Herring

Steve said:
Hi,

I have a class with some static variables:

in MyClass.h
//-------------------------
lass MyClass{
...
public:
static long myVals[4]; // declaration
}
long MyClass:: myVals[4] = {0,0,0,0}; //definition
//----------------------------

Then in another part of my program: (in This.cpp)

MyClass:: myVals[1] = 123;

But then later on when I try to retrieve this: (in That.cpp)

long x = MyClass:: myVals[1] ;

x always equals zero!?


Everything compiles with no errors or warnings, so can anyone point out
why the static is losing its value?
If the sketch above is a good approximation to your real code, then
(a) the definition of myVals is in MyClass.h
(b) both This.cpp and That.cpp include MyClass.h. Therefore
(c) you are _defining_ myVals at least twice, once in each translation
unit. This violates the one definition rule, so anything could happen.
Solution: don't unnecessarily define things in header files.
 

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

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top