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.