Not too long ago a lot of my current projects code base (C++14 back then) was filled with “inline constexpr” specifiers. Then C++17 came along and brought us two things:
- Inline variables
- Implicit inline for constexpr
Or so I thought…
Studying assembly listenings I’ve noticed that quite a lot of my constexpr variabels (and constexpr variable templates) got duplicated for every translation unit. Finding that weird I rechecked the constexpr specifier page on cppreference where at the end of the first paragraph it says
A constexpr specifier used in a function or static member variable (since C++17) declaration implies inline.
Apparently constexpr does not always imply inline, at least not for variables declared in a header file. A quick test where I created a constexpr variable in a header and included it in two files confirmed that.
08001b10 l O .rodata 00000004 constexpr_variable 00000000 l df *ABS* 00000000 main.cpp 08001b30 l O .rodata 00000004 constexpr_variable 00000000 l df *ABS* 00000000 system_stm32f4xx.c
08001b0c w O .rodata 00000004 constexpr_variable
I can’t really comprehend why the committee decided that this would be a good idea. What’s the point of having multiple immutable things? Currently we have a keyword implicitly adding the meaning of another keyword in 2 out of 3 cases and producing overhead in the one case that’s missing. Also you’ll never notice when you forgot to add inline as constexpr definitions never violate ODR…