I have currently a piece a code which look like this:
foo.h
-------------------
extern const std::string NotFound;
foo.cxx
-------------------
const std::string NotFound = "Not Found";
The current approach allow me to write a function that always return a
*reference* to a string when searching through a std::map<std::string,
std::string> even when the key is not found.
const std::string &FindInMap(std::string const &key);
Unfortunately it creates some side effect. Namely if you compile the
library in static libA.a, then create a shared library that links to
this static library libB.so. Then when trying to dlopen/dlclose the
shared lib libB.so, a seg fault occurs when destroying those global symbols.
Any comments on a better approach/solution ?
Thanks,
Mathieu
>Any comments on a better approach/solution ?
Return an object, not a reference. For global variables, there is no
guarantee about order of initialization, and therefore order of
destruction -- as you have seen -- is also not always as expected.
--
Bob Hairgrove
NoSpam...@Home.com
If you write:
const std::string& NotFound() {
const static std::string not_found = "String not found!";
return not_found;
}
then you have some control over your string's creation. I'm assuming --
but in no way whatsoever know, or have reason to think I know -- that
your dynamic library is horking because of something involved in
creating your global string.
But I'll add my askance look to the other reply; the solution above is
/evil/. Do you /need/ evil, or do you /want/ evil? If your program is
not bottlenecking around string-copying, it will execute in microseconds
whether or not you copy a string here and there. And heck, what's wrong
with iterators? Use iterators, love iterators.
Having FindInMap return a reference to a std::string is probably not a
worthwhile optimization. For one, it requires clients to accept the
resulting string by reference to be effective. And reference variables
in a program can be awkward to deal with. Furthermore, if the FindInMap
routine can take advantage of the named value return optimization
(NVRO), then returning a std::string by value would be more efficient.
So I would recommend changing FindInMap to return a std::string by
value. The program could then construct the not found string as needed
from a "not found" literal.
Just to be safe I would measaure the difference in performance after
this change. Personally, I would have to see a measurable hit on
performance before I would want to deal with global life spans, shared
libraries, and static destructor chains.
Greg