Анализатор обнаружил подозрительный цикл. В теле цикла используется один из следующих операторов: 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. |