Fwd: Linking public: static const members in lib*.a's
Hopefully this will come through a bit better. No clue why the formatting on
that last message was so bad. It looked good when I sent it.
,--------------- Forwarded message (begin)
Subject: Linking public: static const members in lib*.a's
From: STH
Steven T. Hatton wrote:
with the results shown at the end of the code listing. The problem seems to be related to my using static const class members. Other similarly configured programs work OK. Can someone tell me what I'm doing wrong here? namespace sth { namespace util { class RgbColor : public Printable_IF { public: static const RgbColor RED; };
namespace sth { util::RgbColor::RgbColor(const unsigned char& r, const unsigned char& g, const unsigned char& b) : m_r(r) , m_g(g) , m_b(b) {}
const util::RgbColor util::RgbColor::RED = util::RgbColor(255,0,0); }
undefined reference to `sth::util::RgbColor::RED' ./sth/libsth.a(ColorTest.o)(.text+0x6f):./sth/ColorTest.cpp:9: undefined
I've seen this kind of problem before. Effectively, you're trying to initialise a static const class member at runtime (i.e. not compile time!) in a static object That doesn't work, though I can't remember why - I don't know if it should work in C++ or if it's implementation defined. There are several solutions. First, I think the code will work if you create a shared library. Similar code does for me. Perhaps a neater solution for you would be to replace the static const variables with static const functions of the form: const util::RgbColor util::RgbColor::RED(){ static util::RgbColor util::RgbColor RED = util::RgbColor(255,0,0); return RED; } That should work unless you're running the code in an insanely multithreaded environment. -- JDL
On Wednesday 08 September 2004 03:31, John Lamb wrote:
Steven T. Hatton wrote:
I've seen this kind of problem before. Effectively, you're trying to initialise a static const class member at runtime (i.e. not compile time!) in a static object That doesn't work, though I can't remember why - I don't know if it should work in C++ or if it's implementation defined.
No, I am specifically trying to initialize it at compile time. What the stupid compiler or linker is trying to do is a different story! ;) The code works if I build all the parts in the same compilation unit.
There are several solutions. First, I think the code will work if you create a shared library. Similar code does for me.
That might be the answer. I haven't attempted that yet.
Perhaps a neater solution for you would be to replace the static const variables with static const functions of the form:
const util::RgbColor util::RgbColor::RED(){ static util::RgbColor util::RgbColor RED = util::RgbColor(255,0,0); return RED; }
That should work unless you're running the code in an insanely multithreaded environment.
For all that, I could probably use a non-constant private static member, have some kind of first load static initialization flag, and only allow access through const functions. But, damnit! The code I posted is correct! I'll see if I get any feedback from the gnu folks explaining what's going on. I wonder if playing around with extern might work? -- Regards, Steven
Steven T. Hatton wrote:
No, I am specifically trying to initialize it at compile time. What the stupid compiler or linker is trying to do is a different story! ;) The code works if I build all the parts in the same compilation unit.
Fair enough, but look at it from the compiler's point of view. If you use a function to initialise a static const and the function is not defined in the same compilation unit, the compiler can't initialise the const at compile time. It's tricker, though I assume it's possible, to design a static linker that could do the additional compilation at link time to assign a value to the const. I think the gnu linker won't do it except, maybe, in simple cases.
I wonder if playing around with extern might work?
Did you mean to type "export". I don't think gcc handles export yet, but if you have any success with export (or extern) I'd like to know. -- JDL
On Wednesday 08 September 2004 12:57, John Lamb wrote:
Steven T. Hatton wrote:
No, I am specifically trying to initialize it at compile time. What the stupid compiler or linker is trying to do is a different story! ;) The code works if I build all the parts in the same compilation unit.
Fair enough, but look at it from the compiler's point of view. If you use a function to initialise a static const and the function is not defined in the same compilation unit, the compiler can't initialise the const at compile time. It's tricker, though I assume it's possible, to design a static linker that could do the additional compilation at link time to assign a value to the const. I think the gnu linker won't do it except, maybe, in simple cases.
I have to confess, I really don't understand all the linkage rules in C++. How is what I'm doing different from using a global static variable? Would that likewise cause problems in similar circumstances?
I wonder if playing around with extern might work?
Did you mean to type "export". I don't think gcc handles export yet, but if you have any success with export (or extern) I'd like to know.
I meant "extern", but I have to confess, I don't know how it might be helpful. I thought it might help if I had a way to explicitly tell the compiler (linker?) that the symbol was external to the translation unit, it might behave differently. -- Regards, Steven
On Wednesday 08 September 2004 12:57, John Lamb wrote:
Steven T. Hatton wrote:
No, I am specifically trying to initialize it at compile time. What the stupid compiler or linker is trying to do is a different story! ;) The code works if I build all the parts in the same compilation unit.
Fair enough, but look at it from the compiler's point of view. If you use a function to initialise a static const and the function is not defined in the same compilation unit, the compiler can't initialise the const at compile time. It's tricker, though I assume it's possible, to design a static linker that could do the additional compilation at link time to assign a value to the const. I think the gnu linker won't do it except, maybe, in simple cases.
I wonder if playing around with extern might work?
Did you mean to type "export". I don't think gcc handles export yet, but if you have any success with export (or extern) I'd like to know.
-- JDL
I finally figured out how to get it to build. I needed to have the library containing RgbColor linked into the final executable. I just added a -l to the g++ command line to get it to link. I'm pretty sure I can get the same result by adding a LIBADD or LDADD to the executable target. -- Regards, Steven
participants (2)
-
John Lamb
-
Steven T. Hatton