Построение вектора string_views из initializer_list

#c #gcc #c 20

#c #gcc #c 20

Вопрос:

Я пытаюсь создать a vector из string_view s из an initializer_list< const char * > , который нормально работал на GCC 9, но после обновления до GCC 10 он выходит из строя во время выполнения.

 #include <vector>
#include <string_view>
#include <cstdio>

int main()
{
    std::vector< std::string_view > const v { { "Before.", "Afterrrrrr." } };
    printf( "%s %zun", v[0].data(), v[0].length() );
    printf( "%s %zun", v[1].data(), v[1].length() );

    return 0;
}
  

Clang также хорошо обрабатывает код, что дает?

Ссылка: https://godbolt.org/z/6s1c61

Комментарии:

1. @TedLyngmo это так, это привлекло мое внимание после обновления компилятора, поэтому я хотел выяснить, почему 🙂

Ответ №1:

В этом определении переменной

 std::vector< std::string_view > const v { { "Before.", "Afterrrrrr." } };
  

вы случайно использовали этот новый конструктор C 20 string_view :

 template<class It, class End>
constexpr basic_string_view(It first, End last);
  

Таким образом, вы создаете только один string_view , используя начало "Afterrrrrr."
в качестве конечного итератора. Это приводит к неопределенному поведению программы.

Это было бы правильным способом:

 std::vector< std::string_view > const v { "Before.", "Afterrrrrr." };
  

Комментарии:

1. Проблема также последовательно исчезает -std=c 17 . Конструктор был добавлен в libstdc в этом коммите , который реализует P1391R4 .