This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/71504] bogus error: accessing value through a glvalue in a constant expression


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71504

Will <will at dash dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |will at dash dot org

--- Comment #4 from Will <will at dash dot org> ---
A motivating example for this error to be given higher priority.

An array_ref wrapper for multidimensional C-arrays T[M][N]...
providing constexpr access via an index operator[]
 -> returns array_ref<T> when T is an array type or
 -> returns T& otherwise for non-array T

https://wandbox.org/permlink/vcAokwqzk5tOF1ok


#include <type_traits>

template <typename T> struct array_ref;

template <typename T> using ref_t = std::conditional_t<
                                    std::is_array_v<T>, array_ref<T>, T&>;

template <typename T, unsigned N> struct array_ref<T[N]>
{
    T* a;  // T (&a)[N]; 
    using const_reference = const ref_t<T>;
    constexpr const_reference operator[](unsigned I) const { return {a[I]}; }
};

template <typename A> array_ref(A&) -> array_ref<A>;

constexpr int a2[2] = {1,2};
static_assert( array_ref{a2}[0] == 1 );

constexpr int a22[2][2] = {{1,2},{3,4}};
static_assert( array_ref{a22}[0][0] == 1 );

> error: non-constant condition for static assertion
 static_assert( array_ref{a22}[0][0] == 1 );
> error: accessing value of 'a22' through a 'const int' glvalue in a constant expression

Clang accepts. (MSVC untested.)

A workaround is to replace the pointer member with a reference member
(a reference member is less flexible and generally discouraged).
So GCC with this bug forces the less flexible implementation afaict -
I couldn't find a workaround that uses a pointer member.

Like std::array, array_ref is intended to provide array copy.
This is why >1D index operations return wrapped array_ref<T>
(the wandbox link includes some static_asserts to illustrate).

Constexpr is a requirement for my application;
a reasonable requirement for a wrapped C-array.

Other multi-dimensional array implementations must've hit this

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]