Today I encountered a some compiler behaviour which seemed rather strange to me. Consider the following code:
#include <iostream>
#include <algorithm>
struct test {
static const int x = 1;
static const int y = 2;
};
int main() {
std::cout << std::min(test::x, test::y) << std::endl;
return 0;
}
When compiled (with either g++ 5.4, 6.3 or clang++ 4.0), the linker complains that it can not resolve the two symbols test::x and test::y.
$ clang++ test.cpp -o test
/tmp/test-3cd074.o: In function `main':
test.cpp:(.text+0xa): undefined reference to `test::x'
test.cpp:(.text+0x14): undefined reference to `test::y'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, when explicitly (and redundantly) casting the static members to their original type, the compilation succeeds:
int main() {
std::cout << std::min(static_cast<const int>(test::x), static_cast<const int>(test::y)) << std::endl;
return 0;
}
This leads to the expected result:
$ clang++ test.cpp -o test && ./test
1
Just outputting the variables via std::cout works without a cast, so does initializing another variable with the values:
std::cout << test::x << std::endl; // Works!
int z = test::y; // Works as well!
Now my question is: Why can't the linker resolve the symbols when the static members are not being casted? Why is accessing the members not a problem when accessing them outside of a template?