This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/71504] bogus error: accessing value through a glvalue in a constant expression
- From: "will at dash dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Sat, 31 Mar 2018 22:45:25 +0000
- Subject: [Bug c++/71504] bogus error: accessing value through a glvalue in a constant expression
- Auto-submitted: auto-generated
- References: <bug-71504-4@http.gcc.gnu.org/bugzilla/>
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