Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V1069. Do not concatenate string literals with different prefixes.

20 Янв 2021

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

Рассмотрим синтетический пример:

// Until C99/C++11
L"Hello, this is my special "
 "string literal with interesting behavior";

До стандартов C11/C++11 в языках C и C++ существовало лишь два типа строковых литералов:

  • "узкий" строковый литерал – " s-char-sequence "
  • "широкий" строковый литерал – L" s-char-sequence "

Конкатенация таких строковых литералов разных типов до C99 и C++11 приводит к неопределенному поведению, и анализатор выдает предупреждение первого уровня на такой случай. Корректный код будет выглядеть так:

// Until C99/C++11
L"Hello, this is my special "
L"string literal with defined behavior";

Начиная с C99 и C++11, если один из строковых литералов имеет префикс, а второй – нет, то поведение определено, и результирующий строковый литерал будет иметь тот же тип, что и строковый литерал с префиксом. В этом случае анализатор не выдает предупреждений:

// Since C99/C++11
L"Hello, this is my special "
 "string literal with "
 "defined behavior";

Начиная со стандарта C11/C++11 в языки были добавлены следующие префиксированные строковые литералы:

  • UTF-8 строковый литерал – u8" s-char-sequence "
  • 16-битный "широкий" строковый литерал – u" s-char-sequence "
  • 32-битный "широкий" строковый литерал – U" s-char-sequence "

Конкатенация UTF-8 и любого "широкого" строкового литерала ведет к ошибке этапа компиляции, и поэтому анализатор не выдает предупреждений:

L"Hello, this is my special "
u8"string literal that won't compile"; // compile-time error

Любые другие комбинации префиксированных строковых литералов ведут к неуточненному поведению. Анализатор в таких случаях выдает предупреждения второго уровня:

// Until C11/C++11
L"Hello, this is my special "
u"string literal with implementation-defined behavior";

L"Hello, this is my special "
U"string literal with implementation-defined behavior";

u"Hello, this is my special "
U"string literal with implementation-defined behavior";

Анализатор также выдает предупреждения третьего уровня для случаев, когда конкатенируются 3 и более строковых литералов, "узкие" и один из префиксированных:

template <typename T>
void foo(T &&val) { .... }
....
void bar()
{
  foo("This" L"is" "strange");
  foo(L"This" "is" L"strange");
}

Несмотря на то, что в современных стандартах поведение определено, такой код выглядит странно и, возможно, потребует дополнительного внимания. Другими словами, такой код провоцирует ошибки, и полезно рассмотреть вопрос о его рефакторинге.