• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: g++ 4.0.2 linking problem
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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
References: 
 >Re: g++ 4.0.2 linking problem (From: David Fang <email@hidden>)

  • Prev by Date: Re: C language dialect and optimization
  • Next by Date: cvs 1.10 vs 1.11
  • Previous by thread: Re: g++ 4.0.2 linking problem
  • Next by thread: No Build options for Rez phase - Xcode2.4
  • Index(es):
    • Date
    • Thread