Это ложноположительная ошибка containerOutOfBoundsIndexExpression cppcheck?

У меня есть следующий код, который я хочу проверить с помощью инструмента cppcheck:

void f()
{
    std::string str = "123";
    const char* end = &str[str.size()];
}

Но когда я запускаю cppcheck, он сообщает о следующих ошибках, которые я считаю ложными срабатываниями:

$ cppcheck oob.cpp
Checking oob.cpp ...
oob.cpp:4:27: error: Out of bounds access in 'str[str.size()]', if 'str' size is 3 and 'str.size()' is 3 [containerOutOfBounds]
    const char* end = &str[str.size()];
                          ^
oob.cpp:4:24: error: Out of bounds access of str, index 'str.size()' is out of bounds. [containerOutOfBoundsIndexExpression]
    const char* end = &str[str.size()];
                       ^

Как я понимаю, std::string должен хранить завершающий нулевой символ вместе с остальными символами строки, поэтому str[str.size()] должен возвращать символ 0, но cppcheck возвращает ошибку. Это ложное срабатывание cppcheck?


person ks1322    schedule 15.12.2020    source источник
comment
Потому что при получении строки C с помощью en.cppreference.com/w/cpp/string /basic_string/c_str должен заканчиваться нулем. Если std::string возвращает указатель на внутренний буфер, нулевой терминатор уже должен быть в этом буфере.   -  person ks1322    schedule 15.12.2020


Ответы (2)


Я считаю, что это ложное срабатывание. Я создал этот билет: https://trac.cppcheck.net/ticket/10048

person Daniel Marjamäki    schedule 17.12.2020

На основе Будет ли std::string всегда заканчиваться нулем в C++ 11? стандарт гарантирует, что std::string завершается 0 [внутренне].

Однако это не позволяет вам ссылаться на этот 0 напрямую, поэтому cppcheck технически корректен.

Обновить

Как указал Томас в комментарии, на самом деле вы можете ссылаться на этот 0-терминатор SINCE C++ 11.

cppcheck имеет настройку для соответствия определенному стандарту: --std=<id> (https://linux.die.net/man/1/cppcheck)

Посмотрите, изменит ли это его поведение.

person Vlad Feinstein    schedule 15.12.2020
comment
Нет, cppcheck --std=c++11 ничего не меняет. Также --std=c++11 используется по умолчанию в cppcheck, так что простое cppcheck без каких-либо параметров совпадает с cppcheck --std=c++11, см. linux .die.net/man/1/cppcheck. - person ks1322; 16.12.2020