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

            Bug ID: 123819
           Summary: [reflection]  promote_strings ->
                    std::define_static_array(views) -> exception:
                    reflect_constant failed'
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lyubomir.filipov at amusnet dot com
  Target Milestone: ---

I'm trying to implement the promote_strings function, mentioned in P3491R3
https://isocpp.org/files/papers/P3491R3.html

I'm using compiler explorer, with gcc trunk:
https://godbolt.org/z/K6z9nKdzx

I have also implemented my own string_view class with public members. The
resulting code is following:

```
#include <algorithm>
#include <meta>
#include <iostream>
#include <vector>
#include <span>
#include <string>

struct MyStringView {

    constexpr MyStringView (const std::string_view& sv)
    :data (sv.data())
    ,len (sv.size()) {}

    constexpr operator std::string_view () const
    {
        return std::string_view (data,len);
    }

    std::string_view::const_pointer data;
    size_t len;
};

constexpr std::vector<std::string> get_strings() {
    return {"Jason", "Was", "Here"};
}

consteval auto promote_strings(std::vector<std::string> vs)
    -> std::span<MyStringView const>
{
    // promote the concatenated strings to static storage
    std::string_view promoted = std::define_static_string(
        std::ranges::fold_left(vs, std::string(), std::plus()));

    // now build up all our string views into promoted
    std::vector<MyStringView> views;
    for (size_t offset = 0; std::string const& s : vs) {
        views.emplace_back(promoted.substr (offset, s.size()));
        offset += s.size();

    }

    // promote our array of string_views
    return std::define_static_array(views);
}

int main (int argc, char** argv)
{   
    constexpr auto views = promote_strings(get_strings());

    for (auto& view: views) {
        std::string_view sv = view;
        std::cout << "\t" << sv << "\n";
    }

        return 0;
}
```

But throws an exception at compile time:

```
<source>: In function 'int main(int, char**)':
<source>:49:57: error: uncaught exception of type 'std::meta::exception';
'what()': 'reflect_constant failed'
   49 |     constexpr auto views = promote_strings(get_strings());
```

The interesting part is that it throws an exception when on line 38 the offset
value is different from 0. If the offset is 0, the code compiles and fills the
resulting span with string views to the beginning of the `promoted` string. I
even can set (at line 38) the size to arbitrary large value and the code will
still compile successfully, so we can see the entire 'promoted' string and that
the `promoted` string is correctly concatenated: `JasonWasHere` - but I cannot
take a string_view from it at offset different from 0 - even offset 1 and size
1 should work, giving a string_view to the second character
  • [Bug c++/123819] New: [re... lyubomir.filipov at amusnet dot com via Gcc-bugs

Reply via email to