The code below triggers error with gcc 'undefined reference Foo::d' and 'undefined reference Foo::i'. Strangely, it happens only if I compile it in -Og, or -O1 optimization mode, but not with -O2 or -O3. Moreover, if I pass constexpr double as parameter for int& and vice versa (see last too calls) -- it does not trigger error.
#include <stdio.h> class Foo { public: static constexpr double d = 10.0; static constexpr int i = 10; }; //class Foo void print_double_ref(const double& v) { printf("v = %g\n", v); } void print_int_ref(const int& n) { printf("n = %i\n", n); } int main() { Foo a; //This part triggers link error with -Og, -O1 //No error with -O2, -O3 print_double_ref(a.d); print_int_ref(a.i); //This part does not trigger link error with -Og, -O1 print_int_ref(a.d); print_double_ref(a.i); } I understand, that problem is somehow related to declaring argument of functions print_double_ref and print_int_ref as references. The questions are:
- Why link error in -Og and -O1 modes only?
- Why passing
constexpr doubleas parameter forconst int&(orconstexpr intas parameter forconst double&does not produce error?
Update: I know that for static const members one should initialize them outside the class. However, constexpr variables must be defined at the point of declaration. Why such a construct is allowed to be compiled then?
static inline .... See here: static members.static constexpr int i = 10;should implyinlineand is therefore a definition (not only a declaration). So there should be no linker error. That's from c++17. Which version of c++ do you use ?