By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,837 Members | 1,667 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,837 IT Pros & Developers. It's quick & easy.

Passing a reference to static-const class member --> link error?

P: n/a
I have written some pretty simple code which works great in Dev Studio
and CodeWarrior, but gcc is giving me link errors. Here is what I've
been able to distill it down to:

namespace Private {
template <class T> struct lengthof;
template <class T, size_t N> struct lengthof<T[N]> { static const
size_t array_size = N; };
}

#define lengthof( x ) Private::lengthof<__typeof__(x)>::array_size

const size_t& Min(const size_t& a, const size_t& b) { return b < a ? b
: a; }

int main (int argc, char * const argv[])
{
char c[1];
printf( "%d", Min( 123, lengthof(c) ) );
}
Trying to build this with GCC4 (via Xcode), I get:
/usr/bin/ld: Undefined symbols:
Private::lengthof<char [1]>::array_size
collect2: ld returned 1 exit status
There are three separate workarounds I could find:
1 -- use "enum" instead of "static const size_t"
template <class T, size_t N> struct lengthof<T[N]> { enum { array_size
= N }; };

2 -- explicitly cast the array_size member to size_t before passing it
to Min
#define lengthof( x ) size_t(
Private::lengthof<__typeof__(x)>::array_size )

3 -- change Min to take values instead of references (the real
program's implementation is templated, however, and I don't want value
passing in the general case).

Why might this be happening? It smells kind of like a GCC bug to me.

Jul 23 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
One more thing I just found--switching to GCC 3.3 instead of 4.0 makes
the problem go away.

Jul 23 '05 #2

P: n/a
With the help of some C++ gurus I found the answer.
You need to explicitly provide a definition of lengthof::array_size.
Just declaring it in the class isn't enough:

namespace Private {
template <class T> struct lengthof;
template <class T, size_t N> struct lengthof<T[N]> { static
const size_t array_size = N; };
template <class T, size_t N> const size_t
lengthof<T[N]>::array_size;
}

Man, GCC4 is testing all of our C++ knowledge to the limits! :) Funny
how no other compiler needs this, and even GCC4 doesn't need it most of
the time.

Jul 23 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.