http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50785
--- Comment #8 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-10-19 12:54:24 UTC --- I agree that the test case should require the definition of the static member, the actual reason being that the constraint in 3.2 p2, "[..] unless it is an object that satisfies the requirements for appearing in a constant expression [..]" is not satisfied, because the operator* of complex is not constexpr. Changing the reference to std::complex by template<class T> struct complex { private: T data[2]; public: constexpr complex(T r = 0, T i = 0) : data{r, i} {} constexpr T real() { return data[0]; } constexpr T imag() { return data[1]; } }; template<class T> constexpr complex<T> operator*(const complex<T>& lhs, const T& rhs) { return complex<T>(lhs.real() * rhs, lhs.imag() * rhs); } also fixes the initial problem, because now the expression complex<double>(0,1)*test::value satisfies the criteria to appear in a constant expression. But I think that the replacement code complex<double> x = complex<double>(0,1)*(1*test::value); should also require the definition of test::value. It could be, that the compiler now reduces the scope of the analysis to the sub-expression (1*test::value). If so, this is either a compiler defect or a core language defect, I'm not sure. It is arguable that the description "[..] unless it is an object that satisfies the requirements for appearing in a constant expression [..]" is somewhat misleading, because it focuses on the object and not on the expression where it is part of. This could be related to CWG #712 in this case.