I'm using the clang that comes bundled with Xcode 9.3, and I'm trying to understand whether the following result is an intentional part of C++17 changes:
#include <iostream>
template<typename T> struct Test {
static const int TEN;
};
template<typename T> constexpr int Test<T>::TEN = 10;
int main(int argc, const char * argv[]) {
std::cout << Test<int>::TEN << std::endl;
return 0;
}
When compiled with c++11 or c++14, this prints "10". However, compiling this with c++17, this prints "0".
What's going on?
Static specifies the lifetime of the variable. A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.
constexpr variable is guaranteed to have a value available at compile time. whereas static const members or const variable could either mean a compile time value or a runtime value. Typing constexpr express your intent of a compile time value in a much more explicit way than const .
static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation. Compilation and execution are disjoint and discontiguous, both in time and space. So once the program is compiled, constexpr is no longer relevant.
The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.
After posting this elsewhere, a clang developer acknowledged that this was a bug in clang-5 c++17 implementation, and that it is fixed in clang-6 onwards.
Thanks to tkausl for his initial comment that showed differing results in clang-6 and gcc, which led me to ask elsewhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With