Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V525. Code contains collection of simil…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C++)
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V525. Code contains collection of similar blocks. Check items X, Y, Z, ... in lines N1, N2, N3, ...

16 Сен 2011

Анализатор обнаружил код, который возможно содержит опечатку. Этот код можно разделить на более мелкие и похожие между собой фрагменты кода. Хотя фрагменты кода похожи, но все же различны. Высока вероятность, что подобный код был создан с использованием подхода Copy-Paste. Сообщение V525 будет выдано в том случае, если есть подозрение, что один из элементов не исправлен в скопированном тексте. Ошибка может находиться в одной из строк, номера которых содержатся в сообщении V525.

Недостатки сообщения V525:

1) Данное диагностическое правило основано на эвристических методах и нередко дает ложное срабатывание.

2) Реализация эвристического алгоритма сложна и занимает более 1000 строк кода на Си++. Поэтому его затруднительно описать в рамках документации. Как следствие пользователю может быть трудно понять, почему выдано то или иное сообщение V525.

3) Диагностическое сообщение относится к нескольким строкам, а не к одной. Указать только одну строку невозможно, так как ошибка может быть в любой из них.

Преимущества сообщения V525:

1) Можно обнаружить ошибки, которые крайне сложно заметить при обзоре кода (code review).

Рассмотрим вначале искусственный пример:

...
float rgba[4];
rgba[0] = object.GetR();
rgba[1] = object.GetG();
rgba[2] = object.GetB();
rgba[3] = object.GetR();

Массив 'rgba' представляет собой цвет и прозрачность некоего объекта. При написании кода, заполняющего массив, вначале была написана строчка "rgba[0] = object.GetR();". Затем это строка была несколько раз скопирована и изменена. Однако в последней строке изменения сделаны не до конца и вместо функции 'GetA()' вызывается 'GetR()'. Анализатор выдает на данный код следующее предупреждение:

V525: The code containing the collection of similar blocks. Check items 'GetR', 'GetG', 'GetB', 'GetR' in lines 12, 13, 14, 15.

Просмотрев строки 12, 13, 14 и 15 можно обнаружить ошибку. Исправленный вариант кода:

rgba[3] = object.GetA();

Теперь рассмотрим несколько примеров, взятых из кода реальных приложений. Первый пример:

tbb[0].iBitmap = 0; 
tbb[0].idCommand = IDC_TB_EXIT; 
tbb[0].fsState = TBSTATE_ENABLED; 
tbb[0].fsStyle = BTNS_BUTTON; 
tbb[0].dwData = 0; 
tbb[0].iString = -1; 
...
tbb[6].iBitmap = 6; 
tbb[6].idCommand = IDC_TB_SETTINGS; 
tbb[6].fsState = TBSTATE_ENABLED; 
tbb[6].fsStyle = BTNS_BUTTON; 
tbb[6].dwData = 0; 
tbb[6].iString = -1;
 
tbb[7].iBitmap = 7; 
tbb[7].idCommand = IDC_TB_CALC; 
tbb[7].fsState = TBSTATE_ENABLED; 
tbb[7].fsStyle = BTNS_BUTTON; 
tbb[6].dwData = 0; 
tbb[7].iString = -1;

Фрагмент кода приведен далеко не полностью. Вырезано более чем половина. Фрагмент писался методом копирования и правки кода. Неудивительно, что в таком большом фрагменте затерялся неверный индекс. Анализатор выдает следующее диагностическое сообщение: "The code containing the collection of similar blocks. Check items '0', '1', '2', '3', '4', '5', '6', '6' in lines 589, 596, 603, 610, 617, 624, 631, 638". Просмотрев данные строки, мы можем исправить дважды повторяющийся индекс '6'. Исправленный вариант кода:

tbb[7].iBitmap = 7; 
tbb[7].idCommand = IDC_TB_CALC; 
tbb[7].fsState = TBSTATE_ENABLED; 
tbb[7].fsStyle = BTNS_BUTTON; 
tbb[7].dwData = 0; 
tbb[7].iString = -1;

Второй пример:

pPopup->EnableMenuItem(
  ID_CONTEXT_EDITTEXT,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_CLOSEALL, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_CLOSE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_SAVELAYOUT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_RESIZE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_REFRESH, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_EDITTEXT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_SAVE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_EDITIMAGE,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_CLONE,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);

Рассматривая данный код, очень сложно найти в нем ошибку. Однако ошибка здесь действительно присутствует. Дважды модифицируется состояние одного и того же пункта меню 'ID_CONTEXT_EDITTEXT'. Выделим две повторяющиеся строки:

------------------------------
pPopup->EnableMenuItem(
  ID_CONTEXT_EDITTEXT,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
------------------------------
pPopup->EnableMenuItem(
  ID_CONTEXT_CLOSEALL, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_CLOSE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_SAVELAYOUT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_RESIZE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_REFRESH, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
------------------------------
pPopup->EnableMenuItem(
  ID_CONTEXT_EDITTEXT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
------------------------------
pPopup->EnableMenuItem(
  ID_CONTEXT_SAVE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_EDITIMAGE,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
pPopup->EnableMenuItem(
  ID_CONTEXT_CLONE,MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);

Возможно это несерьезная погрешность, и одна из строк просто лишняя. А возможно, здесь забыли изменить состояние какого-то другого элемента меню.

К сожалению, анализатор, осуществляя данный вид диагностики, часто ошибается и генерирует ложные срабатывания. Пример кода, приводящий к ложному срабатыванию:

switch (i) {
  case 0: f1 = 2; f2 = 3; break;
  case 1: f1 = 0; f2 = 3; break;
  case 2: f1 = 1; f2 = 3; break;
  case 3: f1 = 1; f2 = 2; break;
  case 4: f1 = 2; f2 = 0; break;
  case 5: f1 = 0; f2 = 1; break;
}

Здесь анализатору не нравится корректный столбец цифр: 2, 0, 1, 1, 2, 0. В подобных ситуациях можно воспользоваться подавлением предупреждений, вписав комментарий //-V525 в конце строки:

switch (i) {
  case 0: f1 = 2; f2 = 3; break; //-V525
  case 1: f1 = 0; f2 = 3; break;
  case 2: f1 = 1; f2 = 3; break;
  case 3: f1 = 1; f2 = 2; break;
  case 4: f1 = 2; f2 = 0; break;
  case 5: f1 = 0; f2 = 1; break;
}

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

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V525.

close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам