https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83484
Bug ID: 83484 Summary: constexpr not evaluated at compile time Product: gcc Version: 7.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: gjl at gcc dot gnu.org Target Milestone: --- The following test case triggers a link failure because the constexpr are not evaluated at compile time: $ g++-8 tmp.cpp -Os -save-temps tmp.o: In function `Port<7>::set(Port<7>::Value)': tmp.cpp:(.text._ZN4PortILi7EE3setENS0_5ValueE[_ZN4PortILi7EE3setENS0_5ValueE]+0x2): undefined reference to `Port<7>::High' tmp.o: In function `main': tmp.cpp:(.text.startup+0x3): undefined reference to `Port<7>::Low' tmp.cpp:(.text.startup+0x1a): undefined reference to `Port<7>::High' collect2: error: ld returned 1 exit status == Test case == unsigned volatile PORTB; template<int p> struct Port { enum class Value : unsigned { High, Low }; static inline void set (Value); static constexpr Value High = Value::High; static constexpr Value Low = Value::Low; }; template<> constexpr Port<7>::Value Port<7>::High; template<> constexpr Port<7>::Value Port<7>::Low; template<> inline void Port<7>::set (Port<7>::Value value) { if (High == value) PORTB |= 2; else PORTB &= ~2; } int main() { Port<7>::set (Port<7>::Low); Port<7>::set (PORTB ? Port<7>::Low : Port<7>::High); } Apart from the link failure you see that even with optimizations turned on and for an almost trivial function call like Port<7>::set (Port<7>::Low), the compiler generates a call. Fot some targets the compiler even generates calls with just 2 instructions (one of which is a return statement). So far I see this for v7 and v8 on x86_64 and avr.