[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 <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
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 <J.D.Lamb@btinternet.com> wrote:
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 <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
On Wed, 06 Jun 2007 08:01:18 +0100 John D Lamb <J.D.Lamb@btinternet.com> wrote:
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 <gaf@blu.org> Boston Linux and Unix user group http://www.blu.org PGP key id:C5061EA9 PGP Key fingerprint:053C 73EC 3AC1 5C44 3E14 9245 FB00 3ED5 C506 1EA9
participants (2)
-
Jerry Feldman
-
John D Lamb