const string in static class

M

msaladin

Hi all,

I spent today with finding an error, I found it, though I don't no why.
I have a class with static constants, like this:

class EXPORT_API BusConstants {
public:
static const std::string PIPE_DIRECTORY;
};

Somewhere else, I declare the String:

const std::string BusConstants::pIPE_DIRECTORY

Then, in some other class, I want to initialize a static logger with
this string:

Category& UBusHelper::logger =
Category::getInstance(BusConstants::pIPE_DIRECTORY);

What is very weird is that I get segmentation faults on Linux and
Solaris, but everything seems to work fine on Windows. My workaround is
to define the string as "const char*", and then it works, because the
compiler automatically remarks this and seems to create a new string
object when I call Category::getInstance. Here is how it works:

class EXPORT_API BusConstants {
public:
static const char* PIPE_DIRECTORY;
};

Somewhere else, I declare the char pointer:

const char* BusConstants::pIPE_DIRECTORY

Does somebody have any idea? My only guess is that static const strings
are not created until some constructor or anything is called. Because
in the class with my constants (BusConstants) I don't have any
constructor, this is why it is only initialized when some other method
of BusConstants is called.I used to program quite a bit in Java, there
this is different? I very appreciate if anybody could reassure my
assumption. Sorry, if this is a bit a naive question.

By the way: The segmentation fault did not happen every time. It only
happened when I had some weird order in how I linked my object files
(one object file per C++ class).

Thanks a lot.
Michael
 
B

Ben Pope

Hi all,

I spent today with finding an error, I found it, though I don't no why.
I have a class with static constants, like this:

class EXPORT_API BusConstants {
public:
static const std::string PIPE_DIRECTORY;
};

Somewhere else, I declare the String:

const std::string BusConstants::pIPE_DIRECTORY

Then, in some other class, I want to initialize a static logger with
this string:

Category& UBusHelper::logger =
Category::getInstance(BusConstants::pIPE_DIRECTORY);

What is very weird is that I get segmentation faults on Linux and
Solaris, but everything seems to work fine on Windows. My workaround is
to define the string as "const char*", and then it works, because the
compiler automatically remarks this and seems to create a new string
object when I call Category::getInstance. Here is how it works:

This is a FAQ:

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12

There are solutions there as well.

Ben Pope
 
R

Rolf Magnus

Hi all,

I spent today with finding an error, I found it, though I don't no why.
I have a class with static constants, like this:

class EXPORT_API BusConstants {
public:
static const std::string PIPE_DIRECTORY;
};

It's a good idea to reserve names with all uppercase for macros only.
Somewhere else, I declare the String:

You mean you define it. The above was the declaration.
const std::string BusConstants::pIPE_DIRECTORY

Without an initializer, a constant is pretty useless.
Then, in some other class, I want to initialize a static logger with
this string:

Category& UBusHelper::logger =
Category::getInstance(BusConstants::pIPE_DIRECTORY);

What is very weird is that I get segmentation faults on Linux and
Solaris, but everything seems to work fine on Windows.
My workaround is to define the string as "const char*", and then it
works, because the compiler automatically remarks this and seems to create
a new string object when I call Category::getInstance. Here is how it
works:

class EXPORT_API BusConstants {
public:
static const char* PIPE_DIRECTORY;
};

Somewhere else, I declare the char pointer:

const char* BusConstants::pIPE_DIRECTORY

Does somebody have any idea? My only guess is that static const strings
are not created until some constructor or anything is called.

Well, static class members are created at program startup, and part of that
creation is that the constructor is called. However, there is no specific
order in which objects defined in different translation units are created.
So it's likely that on the Linux and Solaris machines, you were lucky,
because the string was created after the logger. Otherwise, you wouldn't
have noticed the error.
Because in the class with my constants (BusConstants) I don't have any
constructor, this is why it is only initialized when some other method
of BusConstants is called.

Static members don't have anything to do with the constructor. They belong
to the class, not to instances of it. They are all created at program
startup.
I used to program quite a bit in Java, there this is different? I very
appreciate if anybody could reassure my assumption. Sorry, if this is a
bit a naive question.

By the way: The segmentation fault did not happen every time. It only
happened when I had some weird order in how I linked my object files
(one object file per C++ class).

The oder of initialization might (but isn't required to) depend on the order
in which you give the object files to the linker.
 

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,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top