﻿# Немного о проверке шаблонов

Иногда анализатор PVS\-Studio выдает загадочные сообщения, в которых упоминается шаблонный класс\. Вот пример такого сообщения: V614 Instantiate ReconstructMB<PlaneY, PlaneUV, color\_format, false, 1\>: Uninitialized variable 'iRefFieldTop' used\. Встретившись с таким сообщением и рассматривая код шаблонного класса можно загрустить\. Всё кажется сложным и непонятным\. Но всё не так страшно\. Давайте попробуем разобрать один пример\.

Рассмотрим фрагмент кода, взятый из реального приложения\. 

```cpp
template <typename PlaneY, typename PlaneUV,
          Ipp32s color_format, Ipp32s is_field, Ipp32s is_weight,
          bool nv12_support = false>
class ReconstructMB
{
public:
  ...
  void CompensateMotionChromaBlock(ReconstructParams *pParams,
         Ipp32s iDir, Ipp32s iBlockNumber, Ipp32s iUniDir)
  {
    Ipp32s iRefFieldTop;
    if (is_field)
    {
      if (pParams->is_mbaff)
      {
        iRefFieldTop = pParams->is_bottom_mb ^
                       (pParams->m_iRefIndex[iDir] & 1);
        pParams->m_iRefIndex[iDir] = iRefIndex;
      }
      else
        iRefFieldTop =
          GetReferenceField(pParams->m_pSegDec->m_pFields[iDir],
                            iRefIndex);
      
      if (iRefFieldTop)
      { ..... }
    }
    .....
    interpolateInfo->pointVector.y +=
      (pParams->is_bottom_mb - iRefFieldTop) * 2; // <= V614
    .....
};
```

В общем, что\-то длинное и невразумительное\. Разбираться в таком коде не хочется, но анализатор требует обратить на него внимания\. Я специально взял такой длинный пример\. Хочу показать, что программисту не стоит лениться\. Следует постараться понять, что может не нравиться анализатору\.

Вот сообщение, выданное PVS\-Studio:

V614 Instantiate ReconstructMB<PlaneY, PlaneUV, color\_format, false, 1\>: Uninitialized variable 'iRefFieldTop' used\. umc\_h264\_reconstruct\_templates\.h 227

В строке 227 PVS\-Studio подозревает использование неинициализированной переменной 'iRefFieldTop'\.

Если мы изучим код, то увидим, что переменная 'iRefFieldTop' инициализируется только в том случае, если выполняется условие "if \(is\_field\)"\. Значение 'is\_field' является аргументом шаблона\. Тип этого значения 'Ipp32s'\.

Естественно, никакой ошибки не возникнет, если класс ReconstructMB будет инстанцироваться со значениями "is\_field \!\= 0"\. Например, как\-то так: 

ReconstructMB<PlaneY, PlaneUV, color\_format, 1, 1, false\>  X;

Но нет, анализатор предупреждает не зря\. Если поискать, то можно найти вот такое забавное объявление переменной:

ReconstructMB<PlaneY, PlaneUV, color\_format, false, 0\>  mb;

Видно, что здесь что\-то напутано\. Смотрите, что ожидается и что передаётся:

```cpp
Аргументы шаблона      Аргументы при объявлении переменной
typename PlaneY                      PlaneY
typename PlaneUV                     PlaneUV
Ipp32s color_format                  color_format
Ipp32s is_field                      false
Ipp32s is_weight,                    0
bool nv12_support = false            (none)
```

Странно, что один аргумент типа 'Ipp32s' задаётся равным '0', а другой равным 'false'\. Очень странный стиль программирования\!

Скорее всего, в процессе рефакторинга добавлялись или изменялись параметры шаблона\. А в этом месте забыли исправить объявление переменной 'mb'\. Код компилировался, и никто не заметил опасности\.

В общем\-то, не так важно, как получился такой код\. Важно то, что в программе есть использование неинициализированной памяти\. И анализатор PVS\-Studio это обнаружил\. При этом в сообщении он указал, что ошибка возникнет, когда класс инстанцируется следующим образом: ReconstructMB<PlaneY, PlaneUV, color\_format, false, 1\>\.

Надеюсь, я разъяснил, что означают подобные сообщения анализатора и какую информацию они содержат\.

Желаю вам повышения надёжности от использования анализатора PVS\-Studio\!