Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

error while trying to compile .data() from std::array as a constexpr function in c++20

I was trying to compute an array in compilation time to speed up some functions while i encountered an error which I was unable to resolve with the help of cppreference.

The code boils down to this:

#include <iostream>
#include <array>

template<typename T, size_t size>
constexpr auto giveArray()
{
    std::array<T, size> arr;
    for(size_t i = 0; i < size; ++i)
        arr[i] = 0;
    return arr;
}

constexpr auto arr = giveArray<int,10>().data();

While compiling with: "$ g++ -std=c++20 code.cpp" on ubuntu i get the error that .data() is not a constexpr function while it definitely is. Why am i getting this error and how it can be fixed while still running this function in compilation time and storing only a pointer, not the std::array object?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

To initialize a constexpr variable you need an initializer that is a constant expression. But giveArray<int,10>().data(); is not a constant expression.

From here :

A constant expression is either a glvalue core constant expression that refers to an entity that is a permitted result of a constant expression (as defined below), or a prvalue core constant expression whose value satisfies the following constraints:

  • if the value is an object of class type, each non-static data member of reference type refers to an entity that is a permitted result of a constant expression,
  • if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a non-immediate function, or a null pointer value,
  • if the value is of pointer-to-member-function type, it does not designate an immediate function, and
  • if the value is an object of class or array type, each subobject satisfies these constraints for the value.
    An entity is a permitted result of a constant expression if it is an object with static storage duration that either is not a temporary object or is a temporary object whose value satisfies the above constraints, or if it is a non-immediate function.

The expression giveArray<int,10>().data(); has the value category of prvalue , so it is not a glvalue expression. That means it has to be "a prvalue core constant expression whose value satisfies the following constraints" to be a constant expression. Since the expression evaluates to a pointer type, it has to meet this condition :

  • if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object ([expr.add]), the address of a non-immediate function, or a null pointer value

In this case, it is none of those things so it is not a constant expression. However, if you change the code to like :

constexpr auto my_array = giveArray<int,10>();
constexpr auto arr = my_array.data();

my_array is a constexpr which implies it has static storage duration and data() returns a pointer to that storage, which makes it a constant expression.

In short, this rule makes it so you can’t have a pointer with an invalid pointer value when executing code at compile time.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading