[opensuse-programming] Another C++ question
I have a static string defined in a class:
class Foo
{
public:
...
static const std::string default_name;
...
};
In the C++ file:
const std::string Foo::default_name("standard");
The C++ file is compiled into a shared library, say libfubar.so
The executable is built:
g++ main.cc -o fubar -L<path to libraries> -lfubar
In the real case I have about a dozen libraries. To execute the code, I
manually update LD_LIBRARY_PATH to point to the shared libraries
including the RogueWave STL implementation, but I segfault in
std::string when it is accessing Foo::default_name.
I have tested with and without const. The backtrace shows that we are
in the default constructor, Foo().
As a work around, I could possibly use a c language string (eg. char
*), or even simply define the string as a manifest constant, but my
preference is to use the STL string.
--
Jerry Feldman
On Tue, 2007-06-05 at 16:11 -0400, Jerry Feldman wrote:
I have a static string defined in a class: class Foo { public: ... static const std::string default_name; ... };
In the C++ file: const std::string Foo::default_name("standard");
The C++ file is compiled into a shared library, say libfubar.so
The executable is built: segfault in std::string when it is accessing Foo::default_name.
This looks familiar. I had a similar problem a while back. IIRC, the problem only occurs when you build a shared library and have static data members in a class that use heap memory. I think the code const std::string Foo::default_name("standard"); never gets executed in the shared library, leaving default_name declared but not defined. Some workarounds (I haven't tested them): 1. Put the definition in the header file rather than the .cpp or .cc file (a version of this worked for me). 2. Use something like the following instead: class Foo { ... public: static std::string const& default_name(); }; std::string const& Foo::default_name(){ static std::string const default_name("standard"); return default_name; } Then you have a data-initialiser. I don't think I've tried this. My bet, though, is that you've solved this already. -- JDL --------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
Good ideas. I actually set up a small test case, using my example, and
it worked fine, but I'll take a look at your solution.
Another possibility is to use a static library. In this case, it is the
simplest solution because it only requires relinking the executable.
Additionally, there are a number of cases where there are name
functions in the code where I do exactly what you proposed.
What I don't want to do is to use a #define or a char *.
On Wed, 06 Jun 2007 08:01:18 +0100
John D Lamb
On Tue, 2007-06-05 at 16:11 -0400, Jerry Feldman wrote:
I have a static string defined in a class: class Foo { public: ... static const std::string default_name; ... };
In the C++ file: const std::string Foo::default_name("standard");
The C++ file is compiled into a shared library, say libfubar.so
The executable is built: segfault in std::string when it is accessing Foo::default_name.
This looks familiar. I had a similar problem a while back. IIRC, the problem only occurs when you build a shared library and have static data members in a class that use heap memory. I think the code
const std::string Foo::default_name("standard");
never gets executed in the shared library, leaving default_name declared but not defined.
Some workarounds (I haven't tested them): 1. Put the definition in the header file rather than the .cpp or .cc file (a version of this worked for me).
2. Use something like the following instead: class Foo { ... public: static std::string const& default_name(); };
std::string const& Foo::default_name(){ static std::string const default_name("standard"); return default_name; } Then you have a data-initialiser. I don't think I've tried this.
My bet, though, is that you've solved this already.
-- JDL
--------------------------------------------------------------------- To unsubscribe, e-mail: opensuse-programming+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-programming+help@opensuse.org
-- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
--
Jerry Feldman
On Wed, 06 Jun 2007 08:01:18 +0100
John D Lamb
On Tue, 2007-06-05 at 16:11 -0400, Jerry Feldman wrote:
I have a static string defined in a class: class Foo { public: ... static const std::string default_name; ... };
In the C++ file: const std::string Foo::default_name("standard");
The C++ file is compiled into a shared library, say libfubar.so
The executable is built: segfault in std::string when it is accessing Foo::default_name.
This looks familiar. I had a similar problem a while back. IIRC, the problem only occurs when you build a shared library and have static data members in a class that use heap memory. I think the code
const std::string Foo::default_name("standard");
never gets executed in the shared library, leaving default_name declared but not defined.
Some workarounds (I haven't tested them): 1. Put the definition in the header file rather than the .cpp or .cc file (a version of this worked for me).
2. Use something like the following instead: class Foo { ... public: static std::string const& default_name(); };
std::string const& Foo::default_name(){ static std::string const default_name("standard"); return default_name; } Then you have a data-initialiser. I don't think I've tried this.
My bet, though, is that you've solved this already.
Good ideas. I actually set up a small test case, using my example, and
it worked fine, but I'll take a look at your solution.
Your solution worked fine in the code. I don't know why I didn't think
of it yesterday because I do this elsewhere in the code.
BTW: Sorry for the top posting of my earlier reply :-(.
--
Jerry Feldman
participants (2)
-
Jerry Feldman
-
John D Lamb