C26486 с string_view - PullRequest
       4

C26486 с string_view

2 голосов
/ 24 марта 2020

При компиляции приведенного ниже кода в MSVS с включенными руководящими принципами ядра c ++ выдается предупреждение:

C26486 LIFETIMES_FUNCTION_PRECONDITION_VIOLATION - Ссылка на соответствующие документы Microsoft

using vec_pair = std::vector<std::pair<const std::string_view, const std::string_view>>;

void foo(const vec_pair& vec_pair) noexcept
{
    for (auto [first, second] : vec_pair) //<---- Warning here
    {
        // do stuff
    }
}

int main()
{
    const vec_pair my_vec_pair { {
        {"yes", "no"},
        {"what", "why"},
        {"salt", "pepper"},
    } };

    foo(my_vec_pair);

    return 0;
}

Описание:

Don't pass a pointer that may be invalid to a function. Parameter 0 '$S1' in call to '<move><std::pair<std::basic_string_view<char,std::char_traits<char> > const ,std::basic_string_view<char,std::char_traits<char> > const > & __ptr64>' may be invalid (lifetime.3).

Изменение std :: string_view на std :: string не помогает. Также не выполняется проверка на nullptr как до, так и после для l oop.

Как с этим бороться?

1 Ответ

2 голосов
/ 24 марта 2020

Это ошибка в проверке основных рекомендаций. На самом деле ошибка заключается в понимании структурированных привязок к кортежным типам (таким как std::pair); минимальный пример:

#include <utility>
void foo(std::pair<int, int> p) noexcept {
    auto const [x, y] = p;
}

Похоже, что средство проверки запутано обработкой изобретенной переменной как значения x; см. Случай 2: привязка типа кортежа в объявление структурированного связывания и dcl.struct.bind . Обходной путь должен использовать ref-qualifier из &, так что изобретенная переменная обрабатывается как lvalue:

#include <utility>
void foo(std::pair<int, int> p) noexcept {
    auto const& [x, y] = p;
    //        ^
}

Живой пример .

Примечание: по общему признанию, этот обходной путь не будет работать в этом случае, так как он не справляется с C26445: ссылка на gsl :: span или std :: string_view может указывать на проблему на всю жизнь (gsl .view). Если вы не можете подавить или проигнорировать предупреждение, вам придется использовать first и second, как в старые времена.

...