Информация об изменениях

Сообщение constexpr итераторы и string_view от 20.04.2022 15:49

Изменено 20.04.2022 15:56 Videoman

constexpr итераторы и string_view
Наступил на интересные грабли с MSVC 2017, код:
#include <string_view>

using namespace std::literals;

static constexpr auto str = "ABCD"sv;

template<typename it_t>
constexpr it_t func(it_t it) noexcept
{
    return it + 1;
}

int main()
{
    int result = 0;

    constexpr auto it_beg = str.begin();
    constexpr auto it1 = func(it_beg);
    constexpr auto it2 = func(it1);
    constexpr auto it3 = func(it2);
    constexpr auto it4 = func(it3);

    result = result + (it1 - it_beg);
    result = result + (it2 - it1);
    result = result + (it3 - it2);
    result = result + (it4 - it3);

    return result;
}

Код собирается, но работает не правильно — (возвращает не 4-ку). Глянув на ассемблер можно понять почему: компилятор в памяти генерирует 5-ть экземпляров str и, естественно, их итераторы несовместимы друг с другом и результат из вычитания не определен.
Вопрос к знатокам: что происходит, в чем я не прав, где тупанул? Если убрать constexpr то результат для меня предсказуемый (хоть возможно это и UB).
constexpr итераторы и string_view
Наступил на интересные грабли с MSVC 2017, код:
#include <string_view>

using namespace std::literals;

static constexpr auto str = "ABCD"sv;

template<typename it_t>
constexpr it_t func(it_t it) noexcept
{
    return it + 1;
}

int main()
{
    int result = 0;

    constexpr auto it_beg = str.begin();
    constexpr auto it1 = func(it_beg);
    constexpr auto it2 = func(it1);
    constexpr auto it3 = func(it2);
    constexpr auto it4 = func(it3);

    result = result + (it1 - it_beg);
    result = result + (it2 - it1);
    result = result + (it3 - it2);
    result = result + (it4 - it3);

    return result;
}

Код собирается, но работает не правильно — (возвращает не 4-ку). Глянув на ассемблер, можно понять почему: компилятор в памяти генерирует 5-ть экземпляров str и естественно их итераторы несовместимы друг с другом и результат их вычитания не определен.
Вопрос к знатокам: что происходит, в чем я не прав, где тупанул? Если убрать constexpr то результат для меня предсказуемый (хоть возможно это и UB).