exponenta event banner

Дорогостоящее использование std::string с пустым строковым литералом

Использование std::string с пустой строковой литерал может быть заменен менее дорогостоящими вызовами std::basic_string функции-члены

Описание

В коде C/C + + средство проверки помечает следующие операции:

  • Создание экземпляра std::string с использованием пустого строкового литерала

  • Назначение пустого строкового литерала экземпляру std::string

  • Сравнение экземпляра std::string в пустой строковый литерал

Примечания и ограничения по использованию:

  • Средство проверки не отслеживает происхождение const char переменные указателя, которые пусты и в конечном итоге используются с std::string.

  • Эта проверка частично устарела при использовании текущих компиляторов. Компиляторы, такие как GCC 5.1 и Visual Studio ® 2015, оптимизируют построение из пустого строкового литерала и считают его идентичным построению по умолчанию.

Риск

Предыдущие операции могут быть заменены вызовами конструктора по умолчанию и empty и clear функции-члены std::basic_string шаблон класса. Некоторые компиляторы могут создавать дополнительные инструкции для явных операций по сравнению с использованием встроенных функций-членов. Использование этих операций может снизить производительность скомпилированного кода.

Зафиксировать

Заменить явные операции, включающие пустые строковые литералы, этими вызовами конструктора по умолчанию и функций-членов std::basic_string.

Не использоватьИспользовать
std::string s(""); std::string s;
std::string s = ""; std::string s;
s = ""; s.clear();
if (s == "") if (s.empty())
return ""; return {};
void foo(const std::string& s = "");void foo(const std::string& s = {});(C++ 11) илиfoo(const std::string &str2 = std::string())
foo(""); foo({}) (C++ 11) илиfoo(std::string())
Class::Class() : str("") {//...} Class::Class() : str() {//...}

Повышение производительности может зависеть от используемого компилятора, реализации библиотеки и среды.

Примеры

развернуть все

#include <iostream>
#include <string>

void compareString(const std::string &str1, const std::string &str2="")//Noncompliant
{
	if (str1 == "")//Noncompliant
	{
		std::cout << "The string is empty" << std::endl;
	}
	else
	{
		if (str1.compare(str2) != 0)
		std::cout << str1 << " is not " << str2 << '\n';
	}
}


void bar(){
	compareString("String1");
	compareString("String1","");//Noncompliant
}
В этом примере три строковые операции выполняются с использованием пустых строковых литералов. Polyspace помечает эти операции как неэффективные.

Исправление - использовать функции-члены std::string

Чтобы устранить отмеченные проблемы, замените строковые операции пустыми строковыми литералами вызовами функций-членов std::string. Например:

  • Заменить const std::string &str2="" с const std::string &str2={}

  • Заменить if(str1 == "") с if(str1.empty())

  • Заменить compareString("String1","") с compareString("String1",{})

#include <iostream>
#include <string>

void compareString(const std::string &str1, const std::string &str2 = {})//Compliant
{
	if (str1.empty())//Cmpliant
	{
		std::cout << "The string is empty" << std::endl;
	}
	else
	{
		if (str1.compare(str2) != 0)
		std::cout << str1 << " is not " << str2 << '\n';
	}
}


void bar(){
	compareString("String1");
	compareString("String1",{});//Compliant
}

Информация о результатах

Группа: Производительность
Язык: C++
По умолчанию: Откл.
Синтаксис командной строки: UNNECESSARY_EMPTY_STRING_LITERAL
Воздействие: Низкий
Представлен в R2021a