Re: g++ 4.0.2 linking problem
Re: g++ 4.0.2 linking problem
- Subject: Re: g++ 4.0.2 linking problem
- From: David Fang <email@hidden>
- Date: Sun, 24 Dec 2006 13:53:50 -0500 (EST)
> >> 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