﻿# V1105\. Suspicious string modification using the 'operator\+\='\. The right operand is implicitly converted to a character type\.

Анализатор обнаружил подозрительный код: строковая переменная типа 'std::basic\_string' модифицируется с помощью оператора '\+\='\. При этом правым операндом является выражение арифметического типа\. Из\-за неявных преобразований, проходимых перед вызовом оператора, может быть получен неожиданный результат\.

Рассмотрим пример:

```cpp
void foo()
{
  std::string str;
  str += 1000;     // N1
  str += ' ';
  str += 4.5;      // N2
  str += ' ';
  str += 400.52;   // N3
}
```

Разработчик хотел сформировать строку, состоящую из трёх чисел\. Однако в результате исполнения этого кода получится следующее:

* В строке N1 произойдёт [неявное преобразование](https://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_conversions) из типа 'int' в 'char'\. Результат такого преобразования зависит от [знаковости](https://en.cppreference.com/w/cpp/language/types#Character_types) типа 'char' и версии стандарта C\+\+\. Например, один из возможных вариантов — константа '1000' сконвертируется в значение '\-24', что соответствует символу из расширенной ASCII таблицы\.
* В строке N2 произойдёт [неявное преобразование](https://en.cppreference.com/w/cpp/language/implicit_conversion#Floating.E2.80.93integral_conversions) из типа 'double' в 'char'\. Сначала будет отброшена дробная часть числа '4\.5'\. Поскольку полученное значение '4' умещается в диапазоне значений типа 'char', то в результате конверсии будет получен символ с ASCII кодом 4, который является непечатаемым символом\.
* В строке N3 содержится неопределённое поведение\. После отбрасывания дробной части числа '400\.52' результат не умещается в диапазоне значений типа 'char' \(даже в случае, если он беззнаковый\)\. 

**Примечание\.** Обратите внимание, хоть оба значения — 1000 и 400\.52 — не помещаются в 'char', последствия будут разными\. В случае 1000 мы имеем дело с [сужающим преобразованием](https://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_conversions)\. Такой код компилируется, однако может быть некорректен\. В свою очередь, преобразование числа с плавающей точкой — 400\.52 к типу 'char', согласно стандарту языка, является [неопределённым поведением](https://en.cppreference.com/w/cpp/language/implicit_conversion#Floating.E2.80.93integral_conversions)\.

Во всех подобных случаях необходимо воспользоваться соответствующими функциями для явного преобразования\. Например, функцией '[std::to\_string](https://en.cppreference.com/w/cpp/string/basic_string/to_string)' для конвертации чисел в строки:

```cpp
void foo()
{
  std::string str;
  str += std::to_string(1000);
  str += ' ';
  str += std::to_string(4.5);
  str += ' ';
  str += std::to_string(400.52);
}
```

Если же разработчик изначально планировал добавить символ в строку через его числовое представление, то читаемость такого кода однозначно ухудшается\. Рекомендуется переписать такой код с применением символьного литерала, содержащего или нужный символ, или [escape\-последовательность](https://en.cppreference.com/w/cpp/language/escape):

```cpp
void foo()
{
  std::string str;

  // first option
  str += '*';

  // second option
  str += '\x2A';
}
```

Диагностическое правило выдаёт срабатывание:

* достоверности уровня High, когда правый операнд вещественного типа;
* достоверности уровня Medium, когда правый операнд целого типа в результате неявного преобразования будет усечён;
* достоверности уровня Low, когда правый операнд целого типа в результате неявного преобразования останется с тем же значением и лежит в диапазоне \[0 \.\. 127\] \(символы из нерасширенной таблицы ASCII\)\.