The following compiles in GCC 9 but not in clang 10 and I'm wondering which of the two compilers is standard conforming:
template<typename T>
struct A {
static const T s;
static const T v;
};
template<typename T>
constexpr const T A<T>::s = T(1);
template<typename T>
constexpr const T A<T>::v = A<T>::s;
int main(int, char**) {
constexpr auto a = A<double>::v;
return 0;
}
This is intended to be a minimal example of a bigger issue which is why the fields s
and v
are explicitly declared as const
but are defined as constexpr
, this is intentional.
Is GCC correct to compile that code or is clang correct to reject it?
GCC is slower to compile than clang, so I spend a lot of time compiling, but my final system is (usually) faster with GCC, so I have set GCC as my system compiler.
Not only will your code be faster and smaller, it'll be safer. Code marked constexpr can't bitrot as easily.
A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations. And when a value is computed at compile time instead of run time, it helps your program run faster and use less memory.
GCC and C99 allow an array's size to be determined at run time. This extension is not permitted in standard C++. However, Clang supports such variable length arrays for compatibility with GNU C and C99 programs. If you would prefer not to use this extension, you can disable it with -Werror=vla.
Compilers are only required to treat static const
variables of integral and enum types as constexpr
if they are initialize with a constant expression. This made it possible to use them as array lengths before constexpr
was added to the language.
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