initializing public static const std::string member

C

Christopher

Code compiles, but the string evaluates to NULL in debugger. Using gcc
3.1.1.
Did I not initialize the string properly or is this a compiler bug?

// some.h

#include <string>

namespace ns
{
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}

static const std::string mystring;

void Test();
};
} // namespace

// some.cpp

#include "some.h"

namespace ns
{
const std::string SomeClass::mystring = "Somestring";

void SomeClass::Test()
{
// somestring evaluates to NULL and seg faults here!!!
cout << somestring + somestring;
}

} // namespace
 
K

Kira Yamato

Code compiles, but the string evaluates to NULL in debugger. Using gcc
3.1.1.
Did I not initialize the string properly or is this a compiler bug?

// some.h

#include <string>

namespace ns
{
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}

static const std::string mystring;

void Test();
};
} // namespace

// some.cpp

#include "some.h"

namespace ns
{
const std::string SomeClass::mystring = "Somestring";

void SomeClass::Test()
{
// somestring evaluates to NULL and seg faults here!!!
cout << somestring + somestring;
}

} // namespace

What is 'somestring' in the method SomeClass::Test()?

Where is SomeClass::mystring actually being used?

Perhaps it is better if you can produce a small actual program that
demonstrates the problem.
 
C

Christopher

What is 'somestring' in the method SomeClass::Test()?

Where is SomeClass::mystring actually being used?


Typos - edit:

Code compiles, but the string evaluates to NULL in debugger. Using gcc
3.1.1.
Did I not initialize the string properly or is this a compiler bug?

// some.h

#include <string>

namespace ns
{
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}

static const std::string mystring;

void Test();
};

} // namespace

// some.cpp

#include "some.h"

namespace ns
{
const std::string SomeClass::mystring = "Somestring";

void SomeClass::Test()
{
// somestring evaluates to NULL and seg faults here!!!
cout << mystring + mystring;
}
}

// main.cpp
#include "some.h"

int main()
{
ns::SomeClass tester;

ns::SomeClass.Test();

return 0;
}
 
C

Christopher

Typos - edit:

Code compiles, but the string evaluates to NULL in debugger. Using gcc
3.1.1.
Did I not initialize the string properly or is this a compiler bug?

// some.h

#include <string>

namespace ns
{
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}

static const std::string mystring;

void Test();
};

} // namespace

// some.cpp

#include "some.h"

namespace ns
{
const std::string SomeClass::mystring = "Somestring";

void SomeClass::Test()
{
// somestring evaluates to NULL and seg faults here!!!
cout << mystring + mystring;
}

}

// main.cpp
#include "some.h"

int main()
{
ns::SomeClass tester;
tester.Test();

return 0;

}


I hate having to stare at one screen and manually type things in
another.
 
V

Victor Bazarov

Christopher said:
[..]
Code compiles, but the string evaluates to NULL in debugger. Using gcc
3.1.1.
Did I not initialize the string properly or is this a compiler bug?

What does it mean "the string evaluates to NULL in debugger"?
If you don't know whether the string has been initialised or not,
put the breakpoint in every std::string constructor so that you
know when one is actually constructed.
// some.h

#include <string>

namespace ns
{
class SomeClass
{
public:
SomeClass() {}
~SomeClass() {}

static const std::string mystring;

void Test();
};

} // namespace

// some.cpp

#include "some.h"

namespace ns
{
const std::string SomeClass::mystring = "Somestring";

void SomeClass::Test()
{
// somestring evaluates to NULL and seg faults here!!!

I am not sure I understand that comment.
cout << mystring + mystring;

Not sure 'cout' is defined here. Did you include said:
}
}

// main.cpp
#include "some.h"

int main()
{
ns::SomeClass tester;

ns::SomeClass.Test();

'Test' is non-static member. You cannot call it without
an instance. Did you mean

tester.Test();

?
return 0;
}

Please post the _actual_ code that exhibits the error you are
trying to correct.

While it is possible that it's a bug in the compiler, there is
no way to conclude that if the code you post doesn't even compile.

For the testing purposes (when you're trying to figure out if it
is or isn't a compiler bug), you need to try different things,
like putting everything in the same translation unit.

V
 
C

Christopher

What does it mean "the string evaluates to NULL in debugger"?
If you don't know whether the string has been initialised or not,
put the breakpoint in every std::string constructor so that you
know when one is actually constructed.

It means the string literally evaluates to an unitialized string in
which the _M_p member points to 0x0.

I am not sure I understand that comment.

See above.
Not sure 'cout' is defined here. Did you include <iostream>?

Yes, in the actual code it was included. and the std:: qualifier was
used

'Test' is non-static member. You cannot call it without
an instance. Did you mean

tester.Test();

Yes. Was changed in my own reply to my post.

Please post the _actual_ code that exhibits the error you are
trying to correct.

Unfortunately, such a thing is not possible at work, because the
machines on which the compilers are installed are not connected to a
network with external access, email, or any such thing. They are
totally isolated, with good cause. The best I can do is try to
manually type in an example on another system. A side effect of that
is typos, which I will try to minimize, but they will still appear
once in awhile.

While it is possible that it's a bug in the compiler, there is
no way to conclude that if the code you post doesn't even compile.

It is compilable with the exception of including iostream and
qualifying cout with std::, but I understand your being picky. I
wouldn't want to have to fix every detail of someone elses code
either.
For the testing purposes (when you're trying to figure out if it
is or isn't a compiler bug), you need to try different things,
like putting everything in the same translation unit.

I did indeed try that and the initialization of the string never even
gets hit. It leads me to believe something was screwy with the way
static initialization takes place. I since found out that "static
initialization occurs in no guarenteed order". Makes me wonder, was
this snippet of code occurring from the initialization of some other
static elsewhere? Indeed it was. It seems the problem is that all my
code gets run as a result of some static variable being
instantiated...something I've never seen nor understand. But I guess
I'll have to replace all my static variables with functions that
return references to static variables of their own.
 
K

Kira Yamato

Unfortunately, such a thing is not possible at work, because the
machines on which the compilers are installed are not connected to a
network with external access, email, or any such thing. They are
totally isolated, with good cause. The best I can do is try to
manually type in an example on another system. A side effect of that
is typos, which I will try to minimize, but they will still appear
once in awhile.

Then I suggest you work on that "top-secret" machine to produce a small
standalone program that demonstrates that error first. Then, post that
program onto the forum here.
It is compilable with the exception of including iostream and
qualifying cout with std::, but I understand your being picky. I
wouldn't want to have to fix every detail of someone elses code
either.

We are not trying to pick on you. However, it is nearly impossible to
figure out if the problem in the code is your error or not.
I did indeed try that and the initialization of the string never even
gets hit. It leads me to believe something was screwy with the way
static initialization takes place. I since found out that "static
initialization occurs in no guarenteed order". Makes me wonder, was
this snippet of code occurring from the initialization of some other
static elsewhere? Indeed it was. It seems the problem is that all my
code gets run as a result of some static variable being
instantiated...something I've never seen nor understand. But I guess
I'll have to replace all my static variables with functions that
return references to static variables of their own.

Beside a possible compiler bug, I doubt this is the reason. Beside,
the definitions for SomeClass::Test() and SomeClass::mystring are
already in the same translation unit. So that shouldn't be the problem.

But of course, that was just some madeup code you typed out. Now do
you see why you should post actual code instead of madeup code? Your
madeup code may actually work because it does not reflect the actual
code.

So, once again, I advise that you work out a small actual code *on that
same machine* to reproduce the problem first. Then post that program
here.
 
C

Christopher Pisz

Kira Yamato said:
On 2007-12-17 19:05:03 -0500, Christopher <[email protected]> said:
But of course, that was just some madeup code you typed out. Now do you
see why you should post actual code instead of madeup code? Your madeup
code may actually work because it does not reflect the actual code.

You are missing the point that the original question is not "Can anyone find
the problem for me", but rather, "Can someone help eliminate a possiblilty
for a problem?"

I couldn't possibly type in 50k lines, and it wasn't possible in this case
to figure out what _minimal_ was until the problem was known. It just
happens in this case that minimal would be:
A) some class that gets statically instantiated
B) through its constructor - instantiates another class which has static
members
*I think and am working on verifying that*

However, that was not known at the time of the posting. So instead, I wanted
to narrow it down by verifying that the static initialization in that
example was done correctly (the second half of B). Then, if it was indeed
correct, search through the rest of the code for more possible problems (A
and the first half of B).

You have to make up code when you are dealing with property that is not your
own. Your employer would be quite angry if you posted actual code that was
getting used commercially. I tryed to post a minimal example for the minimal
set of factors that were known. When those factors are found to not be at
fault, then one can safley move on considering others. I apologize for the
typos and not being able to compile an example, but that's all I can
apologize for. If I had tryed to reproduce it, I would have miserably
failed, not knowing the cause. It could take weeks or more of trial and
error, and then of course I would have known my answer and not had a
question in the first place. I think the process of elimination is much more
productive. Once I didn't get any complaints about the code aside from the
typos, from Victor, I was confident that it should work and was able to dig
deeper looking for more possibilities, eliminatiing the possibility of
missing something in the simple scenario of initialising static members.
 
S

Salt_Peter

You are missing the point that the original question is not "Can anyone find
the problem for me", but rather, "Can someone help eliminate a possiblilty
for a problem?"

I couldn't possibly type in 50k lines, and it wasn't possible in this case
to figure out what _minimal_ was until the problem was known. It just
happens in this case that minimal would be:
A) some class that gets statically instantiated
B) through its constructor - instantiates another class which has static
members
*I think and am working on verifying that*

However, that was not known at the time of the posting. So instead, I wanted
to narrow it down by verifying that the static initialization in that
example was done correctly (the second half of B). Then, if it was indeed
correct, search through the rest of the code for more possible problems (A
and the first half of B).

You have to make up code when you are dealing with property that is not your
own. Your employer would be quite angry if you posted actual code that was
getting used commercially. I tryed to post a minimal example for the minimal
set of factors that were known. When those factors are found to not be at
fault, then one can safley move on considering others. I apologize for the
typos and not being able to compile an example, but that's all I can
apologize for. If I had tryed to reproduce it, I would have miserably
failed, not knowing the cause. It could take weeks or more of trial and
error, and then of course I would have known my answer and not had a
question in the first place. I think the process of elimination is much more
productive. Once I didn't get any complaints about the code aside from the
typos, from Victor, I was confident that it should work and was able to dig
deeper looking for more possibilities, eliminatiing the possibility of
missing something in the simple scenario of initialising static members.


Nobody is asking you to Post copyrighted code, some code that
generates the problem would help.
For example the following code will not compile:

int main()
{
std::cout << "a short string";
}

Just as well, if i suggest to you that the following generates an
error:

a = b;

its impossible to know why the above failed if it did.

Try something as follows perhaps, its still rather strange that its we
that need to supply a working scenario (which in this case doesn't
generate that segfault). Note: the member mystring is static, it only
exists in exactly one translation unit. That fact is something you
need to consider should you decide to restate the problem.

// some.h
#ifndef SOME_H_
#define SOME_H_

#include <string>

namespace ns
{
class SomeClass
{
static const std::string mystring;
public:
SomeClass() {}
~SomeClass() {}

void Test();
};
}

#endif

// some.cpp
#include <iostream>
#include "some.h"
using namespace ns;

const std::string SomeClass::mystring("Somestring");

void SomeClass::Test()
{
std::cout << mystring + mystring;
std::cout << std::endl;
}

// main.cpp
#include "some.h"

int main()
{
ns::SomeClass tester;
tester.Test();
}

/*
SomestringSomestring
*/
 
K

Kira Yamato

However, that was not known at the time of the posting. So instead, I wanted
to narrow it down by verifying that the static initialization in that
example was done correctly (the second half of B). Then, if it was indeed
correct, search through the rest of the code for more possible problems (A
and the first half of B).

Ok. Then, no. Possibility eliminated. Search somewhere else in your
code for the problem.

One suggestion, before you execute the program in the debugger, try to
place a watchpoint for SomeClass::mystring instead of a breakpoint. A
watchpoint monitors a memory location and breaks when it changes.
 
C

Christopher Pisz

Kira Yamato said:
On 2007-12-17 21:19:50 -0500, "Christopher Pisz" <[email protected]>
said:
Ok. Then, no. Possibility eliminated. Search somewhere else in your
code for the problem.

One suggestion, before you execute the program in the debugger, try to
place a watchpoint for SomeClass::mystring instead of a breakpoint. A
watchpoint monitors a memory location and breaks when it changes.

Good suggestion. I've kind of been ignoring that for awhile now and need to
learn how to do it in eclipse. I had it down in VS, but they stuck me in a
foreign envirnment. There are a few debugging sessions that would have went
alot easier if I had that available. Thanks for the helps. I know I might
sound argumentetive at times, but you can't convey tone of voice in text.
All the responses were helpful and don't go without my appreciatation. There
are a number of people I need to fed-ex a beer to in this ng.
 
J

James Kanze

Unfortunately, such a thing is not possible at work, because
the machines on which the compilers are installed are not
connected to a network with external access, email, or any
such thing. They are totally isolated, with good cause. The
best I can do is try to manually type in an example on another
system. A side effect of that is typos, which I will try to
minimize, but they will still appear once in awhile.

What's preventing you from compiling it on the machine where you
are connected to the Internet? You may have to retype it (or
use some other mechanism, such as a diskette), but at least, the
code you post will be code which displays the error.
It is compilable with the exception of including iostream and
qualifying cout with std::, but I understand your being picky.
I wouldn't want to have to fix every detail of someone elses
code either.

The problem is that your posted code works, at least if I
correct the "apparent" errors (missing includes, etc.). So
probably, you've copied something wrong. The only way to
advance is for you to post code which doesn't work, in the same
way it doesn't work in your problem. That means that you need a
compiler on the machine you're posting from (g++ is certainly an
option here), that you then test your code, and verify that what
you've "copied" displays the symptoms you describe. Otherwise,
you're just wasting everyone's time, including your own.
I did indeed try that and the initialization of the string
never even gets hit. It leads me to believe something was
screwy with the way static initialization takes place. I since
found out that "static initialization occurs in no guarenteed
order". Makes me wonder, was this snippet of code occurring
from the initialization of some other static elsewhere?

Something, of course, that one could not possibly guess from the
code you posted.
Indeed it was. It seems the problem is that all my
code gets run as a result of some static variable being
instantiated...something I've never seen nor understand.

The constructors of static objects are called during
initialization. Anything any of those constructors calls gets
called.
But I guess I'll have to replace all my static variables with
functions that return references to static variables of their
own.

That's one solution, when it's necessary. I find it a good
policy, however, to first try and eliminate unnecessary dynamic
initialization of statics, and use of other statics in
constructors of objects which might be defined static. Not to
the point of distorting the logic otherwise, of course. But if
your code is really an example of what you're doing, then
replacing the std::string const with a C style string might be
an appropriate solution. (I have a number of cases where I use
a C style array of

struct Elem
{
char const* key;
PODtype value ;
} ;

and std::find_if, rather than std::map< std::string, ... >,
precisely for this reason. Once you've wrapped it in a class,
the small bit of added complexity in the implementation is
isolated, and it makes use much simpler if you don't have to
worry about order of initialization.)
 
J

James Kanze

You are missing the point that the original question is not
"Can anyone find the problem for me", but rather, "Can someone
help eliminate a possiblilty for a problem?"
I couldn't possibly type in 50k lines, and it wasn't possible
in this case to figure out what _minimal_ was until the
problem was known. It just happens in this case that minimal
would be:
A) some class that gets statically instantiated
B) through its constructor - instantiates another class which has static
members
*I think and am working on verifying that*
However, that was not known at the time of the posting. So
instead, I wanted to narrow it down by verifying that the
static initialization in that example was done correctly (the
second half of B). Then, if it was indeed correct, search
through the rest of the code for more possible problems (A and
the first half of B).

You're missing the point. Had you compiled and run the code you
posted, after correcting the obvious typos, you'd have found
that it works. You wouldn't need to post here for that. Your
question suggested that there was something that didn't work in
the code you posted. Since no one here can duplicate the error,
there's no way we can help you.
You have to make up code when you are dealing with property
that is not your own.

Of course. And no one wants you to post 50 000 lines of code
even if you could. You should, however, verify that the small
example you post displays the symptom you are asking about. If
not, you're just wasting your time and ours.

Often, of course, getting the small sample to display the
symptom will provide the insight as to where the error is coming
from, and you won't have to post. (I've experienced this once
or twice when preparing bug reports for g++. My original small
example would not display the bug, and in trying to find what
actually triggered it, incorporating different aspects of my
original code into the example, I've found that the "bug" was
actually an error in my own code.)
Your employer would be quite angry if you posted actual code
that was getting used commercially. I tryed to post a minimal
example for the minimal set of factors that were known. When
those factors are found to not be at fault, then one can
safley move on considering others. I apologize for the typos
and not being able to compile an example, but that's all I can
apologize for. If I had tryed to reproduce it, I would have
miserably failed, not knowing the cause. It could take weeks
or more of trial and error, and then of course I would have
known my answer and not had a question in the first place. I
think the process of elimination is much more productive. Once
I didn't get any complaints about the code aside from the
typos, from Victor, I was confident that it should work and
was able to dig deeper looking for more possibilities,
eliminatiing the possibility of missing something in the
simple scenario of initialising static members.

You'd have gotten that information much more quickly by trying
to compile your small example.
 

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,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top