V612. Unconditional 'break/continue/return/goto' within a loop.
Анализатор обнаружил подозрительный цикл. В теле цикла используется один из следующих операторов: break, continue, return, goto. Эти операторы выполняются всегда, без каких либо условий.
Рассмотрим соответствующие примеры:
do {
X();
break;
} while (Foo();)
for (i = 0; i < 10; i++) {
continue;
Foo();
}
for (i = 0; i < 10; i++) {
x = x + 1;
return;
}
while (*p != 0) {
x += *p++;
goto endloop;
}
endloop:
Показанные выше примеры циклов конечно искусственны и малоинтересны. Давайте рассмотрим фрагмент кода, найденный в одном из настоящих приложений. Для большей наглядности код функции сокращён.
int DvdRead(....)
{
....
for (i=lsn; i<(lsn+sectors); i++){
....
// switch (mode->datapattern){
// case CdSecS2064:
((u32*)buf)[0] = i + 0x30000;
memcpy_fast((u8*)buf+12, buff, 2048);
buf = (char*)buf + 2064; break;
// default:
// return 0;
// }
}
....
}
Часть строк в функции закомментировано. Беда в том, что забыли закомментировать оператор "break".
Когда комментариев не было, "break" был внутри тела "switch". Когда "switch" закомментировали, оператор "break" стал досрочно завершать цикл. В результате тело цикла выполняется только один раз.
Корректный вариант кода:
buf = (char*)buf + 2064; // break;
Следует отметить, что диагностическое правило V612 достаточно сложно. Учитывается множество ситуаций, когда использование оператора break/continue/return/goto совершенно корректно. Рассмотрим для примера несколько ситуаций, когда предупреждение V612 выводиться не будет.
1) Наличие условия.
while (*p != 0) {
if (Foo(p))
break;
}
2) Специальные приёмы, как правило, используемые в макросах:
do { Foo(x); return 1; } while(0);
3) Обход оператора 'continue' с помощью 'goto':
for (i = 0; i < 10; i++) {
if (x == 7) goto skipcontinue;
continue;
skipcontinue: Foo(x);
}
Возможны и другие приёмы, которые используются на практике, но про которые мы не знаем. Если вы заметили, что анализатор выдаёт ложное предупреждение V612, просим написать нам и прислать соответствующие примеры. Мы изучим их и постараемся реализовать исключения для подобных случаев.
Данная диагностика классифицируется как:
|
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V612. |