Иногда анализатор PVS-Studio выдает загадочные сообщения, в которых упоминается шаблонный класс. Вот пример такого сообщения: V614 Instantiate ReconstructMB<PlaneY, PlaneUV, color_format, false, 1>: Uninitialized variable 'iRefFieldTop' used. Встретившись с таким сообщением и рассматривая код шаблонного класса можно загрустить. Всё кажется сложным и непонятным. Но всё не так страшно. Давайте попробуем разобрать один пример.
Рассмотрим фрагмент кода, взятый из реального приложения.
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;
Видно, что здесь что-то напутано. Смотрите, что ожидается и что передаётся:
Аргументы шаблона Аргументы при объявлении переменной
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!