Connecting Tech Pros Worldwide Forums | Help | Site Map

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

John Stiles
Guest
 
Posts: n/a
#1: Jul 23 '05
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.


John Stiles
Guest
 
Posts: n/a
#2: Jul 23 '05

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


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

John Stiles
Guest
 
Posts: n/a
#3: Jul 23 '05

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


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.

Closed Thread