c++ - undefined reference for static constexpr on g++ 4.9 with no optimisation -
i have following code:
#include<chrono> #include<iostream> using namespace std::chrono_literals; #define msg "hello" #define dur 1000ms class mwe{ public: static constexpr auto msg = msg; static constexpr auto dur_1 = dur; static constexpr std::chrono::milliseconds dur_2 = dur; static const std::chrono::milliseconds dur_3; static constexpr decltype(dur) dur_4 = dur; }; constexpr std::chrono::milliseconds mwe::dur_2; const std::chrono::milliseconds mwe::dur_3 = dur; constexpr decltype(dur) mwe::dur_4; int main(void) { std::cout << "str: " << mwe::msg << std::endl; std::cout << "dur_1: " << mwe::dur_1.count() << std::endl; std::cout << "dur_2: " << mwe::dur_2.count() << std::endl; std::cout << "dur_3: " << mwe::dur_3.count() << std::endl; std::cout << "dur_4: " << mwe::dur_4.count() << std::endl; }
if compile (g++ 4.9), via
g++ -std=c++14 -o2 test.cpp
everything works expected, if compile via
g++ -std=c++14 -o0 test.cpp
i following error:
undefined reference `mwe::dur_1'
i way, dur_1 defined , declared most, doesn't work g++ in version, if no optimisations enabled. because other ways know (dur_2, dur_3, dur_4) have drawbacks (redundancy of value, no auto type deduction, if example change 1000ms 1s, aso.)
do know, if gcc bug, compilation works on production mode, doesn't work without optimisation?
and there anoter possible way of getting working, without defining location dur_x outside of class?
it not bug in compiler; bug in you.
you odr-used dur1
never defined it. and, no, neither constexpr
nor inline initialiser make declaration definition.
[c++11, c++14: 9.4.2/3]:
if non-volatile conststatic
data member of integral or enumeration type, declaration in class definition can specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression (5.19). astatic
data member of literal type can declared in class definitionconstexpr
specifier; if so, declaration shall specify brace-or-equal-initializer in every initializer-clause assignment-expression constant expression. [ note: in both these cases, member may appear in constant expressions. —end note ] the member shall still defined in namespace scope if odr-used (3.2) in program , namespace scope definition shall not contain initializer.
as always, optimisation levels may affect extent compiler able and/or willing report such mistakes.
you may write following avoid so-called "problems" identify:
#include<chrono> using namespace std::chrono_literals; #define dur 1000ms struct t { static constexpr auto dur_1 = dur; }; constexpr decltype(t::dur_1) t::dur_1;
Comments
Post a Comment