Reputation: 640
I was trying to use a local class as a way to simulate local functions. The local class defines several static helper functions, where each static functions needs to access a static array defined in the function scope. The thing is working for a normal function, but I have a linking error when using a template function. The code is:
#include <iostream>
double test_local (double x)
{
static const double coeff[3]={ 0, 1, 2 };
struct local_functions
{
static double f0 (double x)
{
static const double c0=coeff[0]+coeff[1];
return c0+x;
}
static double f1 (double x)
{
static const double c1=coeff[1]+coeff[2];
return c1+x;
}
static double f2 (double x)
{
static const double c2=coeff[2]+coeff[0];
return c2+x;
}
};
return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
template<class t>
t test_local_tmpl (t x)
{
static const t coeff[3]={ 0, 1, 2 };
struct local_functions
{
static t f0 (double x)
{
static const t c0=coeff[0]+coeff[1];
return c0+x;
}
static t f1 (t x)
{
static const t c1=coeff[1]+coeff[2];
return c1+x;
}
static t f2 (t x)
{
static const t c2=coeff[2]+coeff[0];
return c2+x;
}
};
return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
int main (int argc, char** argv)
{
double result=test_local (1e0);
// uncommenting next line generates a linking error
// double result_tmpl=test_local_tmpl (1e0);
std::cout << result << std::endl;
return 0;
}
the non template function works fine (it prints 9), while if I try to invoke the template version, it compiles fine but does not link under g++-4.6:
g++ -c -g local_class.cpp && g++ local_class.o -o local_class
Undefined symbols:
"coeff", referenced from:
double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o
double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o
double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o
double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o
double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o
double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Is this the expected beahaviour, i'm missing something or what?
Upvotes: 1
Views: 1693
Reputation: 640
Workaround to circumvent the problem while waiting for a genuine solution from the gcc developers. I must admit that my final decision was to switch to a traditional implementation without helper functions. It is much less elegant (of course) but works and it is all that matters.
Anyway I present the "solution" here since it could be useful in other contexts (maybe). Hope the code formatting will not hurt your eyes :) this time.
#include <iostream>
#include <complex>
template<class t>
t test_local_tmpl (t x)
{
struct local_functions
{
static const t* coeff ()
{
static const t c[]={0,1,2};
return c;
}
static t f0 (t x)
{
static const t c0=coeff()[0]+coeff()[1];
return c0+x;
}
static t f1 (t x)
{
static const t c1=coeff()[1]+coeff()[2];
return c1+x;
}
static t f2 (t x)
{
static const t c2=coeff()[2]+coeff()[0];
return c2+x;
}
};
return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
int main (int argc, char** argv)
{
std::cout << test_local_tmpl (1e0) << std::endl;
std::cout << test_local_tmpl (std::complex<double>(1e0)) << std::endl;
return 0;
}
And the output is
$ g++-mp-4.6 -c -g local_class.cpp && g++-mp-4.6 local_class.o -o local_class
$ ./local_class
9
(9,0)
Anyway it seems that local classes are such a corner feature in the language, that probably they never did a trip out from Alexandrescu's book on C++ designs. The fact that the bug was not discovered before confirms this IMHO.
Upvotes: 0
Reputation: 506905
This is a GCC bug. There is no error in your code. Please file a bug report.
Upvotes: 1