I have the following helper function:
template<typename T, std::size_t N> constexpr std::size_t Length(const T(&)[N]) { return N; }
Which returns the length of a static array. In the past this always has worked but when I do this:
struct Foo { unsigned int temp1[3]; void Bar() { constexpr std::size_t t = Length(temp1); // Error here } };
I get an error when using MSVS 2017:
error C2131: expression did not evaluate to a constant note: failure was caused by a read of a variable outside its lifetime note: see usage of 'this'
I was hoping someone can shed light on what I'm doing wrong.
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.
const can only be used with non-static member functions whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.
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.
In C++11, constexpr member functions are implicitly const.
MSVC is correct. Length(temp1)
is not a constant expression. From [expr.const]p2
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part of e;
temp1
evaluates this
implicitly (because you are referring to this->temp1
), and so you don't have a constant expression. gcc and clang accept it because they support VLAs as an extension (try compiling with -Werror=vla
or -pedantic-errors
).
Why isn't this allowed? Well, you could access the underlying elements and potentially modify them. This is completely fine if you are dealing with a constexpr
array or an array that is being evaluated as a constant expression, but if you are not, then you cannot possibly have a constant expression as you will be manipulating values that are set at run time.
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