V806. Decreased performance. The expression of strlen(MyStr.c_str()) kind can be rewritten as MyStr.length().
Анализатор обнаружил конструкцию, которую потенциально можно оптимизировать. Длина строки, находящейся в контейнере, вычисляется с помощью функции strlen() или аналогичной ей. Это лишнее действие, поскольку контейнер имеет специальную функцию для получения длины строки.
Рассмотрим пример:
static UINT GetSize(const std::string& rStr)
{
return (strlen(rStr.c_str()) + 1 );
}
Этот код взят из реального приложения. Обычно такие забавные фрагменты кода получаются в процессе неаккуратного рефакторинга. Этот код медленен и более, того, он возможно вообще не нужен. Можно просто в нужных местах писать выражение "string::length() + 1".
Если всё-таки хочется сделать специальную функцию, для получения длины строки вместе с терминальным нулём, то она должна выглядеть так:
inline size_t GetSize(const std::string& rStr)
{
return rStr.length() + 1;
}
Примечание
Следует помнить, что действия "strlen(MyString.c_str())" и "MyString.length()" не всегда дают одинаковый результат. Различия будут в том случае, если строка содержит нулевые символы помимо терминального нуля. Однако подобные ситуации можно считать плохим дизайном и сообщение V806 является поводом задуматься над рефакторингом. Даже если программист, написавший такой код, хорошо знает принципы его работы, этот код будет сложен для понимания его коллегам. Коллеги будут гадать, почему написано именно так и могут заменить вызов функции "strlen()" на "length()", внеся ошибку в программу. Следует не лениться и сделать код таким, чтобы принципы его работы были понятны стороннему программисту. Например, если в строке могут быть нулевые символы, то, скорее всего, это вовсе не строка, а массив байт. И тогда нужно использовать класс std::vector или завести свой собственный класс.