I have some linking issues which I do not understand.
Here are the source:
#include <iostream>
template < typename T >
struct CompressedEnums {
CompressedEnums () : data(0) {}
T get() const {
return (T)(data);
}
void set(const T& value) {
data = value;
}
unsigned data;
};
namespace Bbs_detail {
enum inner_type { BB0 = 0 , BB1 = 1 , BB2 = 2 };
typedef inner_type E;
};
struct Bbs {
static const size_t size = 3;
typedef Bbs_detail::inner_type inner_type;
typedef inner_type E;
static const Bbs_detail::E BB0 = Bbs_detail::BB0;
static const Bbs_detail::E BB1 = Bbs_detail::BB1;
static const Bbs_detail::E BB2 = Bbs_detail::BB2;
};
std::ostream& operator<<(std::ostream& o, const Bbs::E& e) {
switch(e) {
case Bbs::BB0: o << "BB0"; return o;
case Bbs::BB1: o << "BB1"; return o;
case Bbs::BB2: o << "BB2"; return o;
}
return o;
};
int main(int argc, const char *argv[]) {
CompressedEnums< Bbs::E > l;
l.set(Bbs::BB0);
Bbs::E x = l.get();
std::cout << x << std::endl;
return 0;
}
When I compile this with -O3 it works, but I get linker errors with -O0. Ih have tried both with gcc 4.6.2 and and gcc 4.7.
When compiling with clang 3.0 I get linker errors regardless of the optimization level.
Linker errors:
/tmp/cch116DO.o: In function `main':
test.cxx:(.text+0x8f): undefined reference to `Bbs::BB0'
collect2: error: ld returned 1 exit status
Is this because I’m doing something illegal?
I was of the opinion that static const members of integral types can be initialized in-class, isn’t that right?
Citing the C++98 standard, 9.4.2 Static data members:
So you have to define the constant members is Alan Stokes pointed in his answer. If you don’t do that, and the compiler manages to avoid any reference to the variable, because it is constant and it already knows the value, you may do without it. But no guarantees about that.
Curiously enough in the C++11 draft, there are a few additional notes about
constexprand brace initializers, and then:Then, in point 3.2 it defines what odr-used means:
That is, in C++11 you have the guarantee not to need the member definition if all your uses of the constant member are in constant expressions: