﻿# C\# программист, испытай себя \-найди ошибку

Анализатор PVS\-Studio регулярно пополняется новыми диагностическими правилами\. Что интересно, часто диагностики обнаруживают подозрительные фрагменты кода еще до окончания всех работ\. Например, в процессе тестирования на open\-source проектах\. Одной из подобных интересных 'находок' и хотелось бы поделиться сегодня с вами\.

![0792_StringBuilder_BounceCastle_ru/image1.png](https://import.viva64.com/docx/blog/0792_StringBuilder_BounceCastle_ru/image1.png)

Как говорилось выше, один из этапов тестирования диагностического правила \- проверка его работы на реальной кодовой базе\. Для этого используется набор отобранных open\-source проектов, для которых проводится анализ\. Очевидное преимущество такого подхода \- возможность посмотреть, как ведёт себя диагностическое правило в "реальных условиях"\. Менее очевидное \- иногда находится что\-то настолько интересное, что про это и заметку не грех написать\. :\)

Итак, предлагаю посмотреть на код из проекта Bouncy Castle C\# и найти в нём ошибку:

```cpp
public static string ToString(object[] a)
{
  StringBuilder sb = new StringBuilder('[');
  if (a.Length > 0)
  {
    sb.Append(a[0]);
    for (int index = 1; index < a.Length; ++index)
    {
      sb.Append(", ").Append(a[index]);
    }
  }
  sb.Append(']');
  return sb.ToString();
}
```

Для тех, кто любит подглядывать, я добавил картинку, чтобы сохранить интригу\.

![0792_StringBuilder_BounceCastle_ru/image2.png](https://import.viva64.com/docx/blog/0792_StringBuilder_BounceCastle_ru/image2.png)

Уверен, многие не смогли найти ошибку без открытия IDE или документации к классу _StringBuilder_\. Ошибка допущена при вызове конструктора:

```cpp
StringBuilder sb = new StringBuilder('[');
```

Собственно, об этом и предупреждает статический анализатор PVS\-Studio: [V3165](https://pvs-studio.ru/ru/docs/warnings/v3165/) Character literal '\[' is passed as an argument of the 'Int32' type whereas similar overload with the string parameter exists\. Perhaps, a string literal should be used instead\. Arrays\.cs 193\.

Программист хотел создать экземпляр типа _StringBuilder_, строка в котором будет начинаться с символа '\['\. Однако из\-за опечатки будет получен объект ёмкостью под 91 элемент, не содержащий символов\.

Это произошло из\-за того, что вместо двойных кавычек использовались одинарные, что привело к вызову не той перегрузки конструктора: 

```cpp
....
public StringBuilder(int capacity);
public StringBuilder(string? value);
....
```

При вызове конструктора символьный литерал '\[' будет неявно приведен к соответствующему значению типа _int_ \(91 в Unicode\)\. Это приведет к вызову конструктора с параметром типа _int_, задающим начальную вместимость\. Программист же хотел вызвать конструктор, задающий начало строки\.

Для исправления ошибки следует заменить символьный литерал на строковый \(т\.е\. использовать "\[", а не '\['\), что позволит вызвать правильную перегрузку конструктора\.

Мы решили не ограничиваться этим паттерном и расширили случаи, которые рассматривает диагностика\. В результате, кроме символьных литералов, сейчас рассматриваются и другие выражения типа _char_, а также, аналогично конструкторам, проверяются методы\. 

Диагностика, срабатывание которой было описано выше, была добавлена в релизе PVS\-Studio 7\.11\. Вы сами можете [загрузить последнюю версию анализатора](https://pvs-studio.ru/ru/pvs-studio/download/) и посмотреть на что способна не только диагностика V3165, но и другие диагностики для языков C, C\+\+, C\# и Java\.

Кстати, идеи диагностик нам часто предлагают сами пользователи\. Так получилось и в этот раз \- спасибо пользователю [Krypt](https://habr.com/en/users/krypt/) с ресурса Habr\. Если у вас также есть идеи диагностических правил \- [не стесняйтесь предлагать их](https://pvs-studio.ru/ru/about-feedback/)\!

**P\.S\.** В текущей кодовой базе проекта данная ошибка уже исправлена\. Однако это не отменяет того факта, что какое\-то время она существовала в коде, и что статический анализ позволяет выявлять подобные проблемы и исправлять их на самых ранних этапах\.