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

            Bug ID: 123379
           Summary: constexpr template for does not work with temporary
                    std::span
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ivan.lazaric.gcc at gmail dot com
  Target Milestone: ---

Code:
```cpp
#include <print>
#include <span>

constexpr int data[] = {1, 2, 3};
constexpr auto range = std::span(data);

int main() {
    template for (constexpr auto el : std::span(data))
        std::println("{}", el);
}
```

Expected for it to compile and produce following output on execution:
```
1
2
3
```

Instead this fails to compile with error:
```
/opt/GCC-REFL/include/c++/16.0.0/bits/stl_iterator.h: In function ‘int main()’:
in ‘constexpr’ expansion of ‘(& __for_range )->std::span<const int,
3>::begin()’
/home/ilazaric/repos/ALL/ivl/reflection/example.cpp:8:31:   
    8 |         std::println("{}", el);
      |                               ^
in ‘constexpr’ expansion of ‘__gnu_cxx::__normal_iterator<const int*,
std::span<const int, 3>::__iter_tag>(((const std::span<const int,
3>*)this)->std::span<const int, 3>::_M_ptr)’
/opt/GCC-REFL/include/c++/16.0.0/span:328:16:   
  328 |       { return iterator(this->_M_ptr); }
      |                ^~~~~~~~~~~~~~~~~~~~~~
/opt/GCC-REFL/include/c++/16.0.0/bits/stl_iterator.h:1059:9: error: the value
of ‘<temporary>’ is not usable in a constant expression
 1059 |       : _M_current(__i) { }
      |         ^~~~~~~~~~~~~~~
/home/ilazaric/repos/ALL/ivl/reflection/example.cpp:8:31: note: ‘<temporary>’
was not declared ‘constexpr’
    8 |         std::println("{}", el);
      |                               ^
In file included from /opt/GCC-REFL/include/c++/16.0.0/format:52:
in ‘constexpr’ expansion of ‘(& __for_range )->std::span<const int, 3>::end()’
/home/ilazaric/repos/ALL/ivl/reflection/example.cpp:8:31:   
/opt/GCC-REFL/include/c++/16.0.0/span:333:31: error: the value of ‘<temporary>’
is not usable in a constant expression
  333 |       { return iterator(this->_M_ptr + this->size()); }
      |                         ~~~~~~^~~~~~
/home/ilazaric/repos/ALL/ivl/reflection/example.cpp:8:31: note: ‘<temporary>’
was not declared ‘constexpr’
    8 |         std::println("{}", el);
      |                               ^
```

Godbolt example:
https://godbolt.org/z/1nYvcEx33

If instead the std::span was not a temporary:
```cpp
#include <print>
#include <span>

constexpr int data[] = {1, 2, 3};
constexpr auto range = std::span(data);

int main() {
    template for (constexpr auto el : range)
        std::println("{}", el);
}
```

This successfully compiles and produces expected output.

Godbolt example:
https://godbolt.org/z/qbPM1c7cT


I came across this while exploring the reflection implementation branch.
This comes out naturally from constructs like:
```cpp
template for (constexpr auto member :
define_static_array(nonstatic_data_members_of(^^T))) {
  ...
}
```

The proposal that introduced define_static_array gives such constructs as
examples:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3491r3.html#with-expansion-statements


Might be related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101557 ,
unsure
  • [Bug c++/123379] New: const... ivan.lazaric.gcc at gmail dot com via Gcc-bugs

Reply via email to