Re: g++ 4.0.2 linking problem
Re: g++ 4.0.2 linking problem
- Subject: Re: g++ 4.0.2 linking problem
- From: "Edward K. Chew" <email@hidden>
- Date: Wed, 27 Dec 2006 13:22:10 -0500
Ah, I see what you mean. You just need to stick a
const int Foo::kMaxBar;
in some source file without giving it a value to avoid a multiple
definition error. The linker seems to be happy now. Thanks.
-Ted
On 24-Dec-06, at 1:53 PM, David Fang wrote:
struct Foo
{
static const int kMaxBar = 100;
int bar;
int bestBar() const;
};
I think you need a
static const int Foo::kMaxBar = 100;
outside the struct/class.
BJ is correct. Even though you're allowed to define static integers
in-class, you still need to define it out-of-class once for linking
purposes, because that constant is bound to a variable.
Well, I haven't got Stroustrup in front of me at the moment, but I
was under the impression it is okay to initialize static constants
within a class in modern C++, provided they are integer types. At
any rate, my real code uses the constant elsewhere within the class
declaration, so I need it defined early on.
My best guess is that the compiler/linker is somehow getting mixed up
about int, const int, and constant methods. Here are a number of
workarounds I have found which seem to placate the linker:
int bestBar() /* no const */ { return bar < kMaxBar ? bar :
kMaxBar; }
int bestBar() const { return bar < kMaxBar ? (int)bar : kMaxBar; }
int bestBar() const { return bar < kMaxBar ? bar : (int)kMaxBar; }
Your suspicions are close. I believe what is happening in these
fake-workarounds is that the compiler is using *value* semantics
where the
constness is not guaranteed.
Consider your original:
int bestBar() const { return bar < kMaxBar ? bar : kMaxBar; }
The conditional operator can deduce both branches to type 'const int&'
which generates a reference to your static variable, hence the linker
error to undefined symbol.
In your three versions above, casting and the non-constness degrade
the
operands to type 'int' (value, not reference), thereby eliding the
reference to kMaxBar, using the in-class defined value instead, as
if it
were an enum because the definition is in-class. Any other code that
emits a *reference* to kMaxBar would still result in the same
undefined
reference, until you define it.
It seems odd that I would have to do this, and I am tempted to file a
bug, but I thought I'd check here first to see if I am breaking any
subtle C++ rules. (It wouldn't be the first time...)
Summary: The only relevant rule here is that you need to define in-
class
integer constants once in some translation unit, for linkage purposes.
The 'strange' effects you've observed are an effect of the compiler
eliding the reference through implicit type-conversions.
HTH,
Fang
David Fang
Computer Systems Laboratory
Electrical & Computer Engineering
Cornell University
http://www.csl.cornell.edu/~fang/
-- (2400 baud? Netscape 3.0?? lynx??? No problem!)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden