Является ли этот статический анализ предупреждением о ложном срабатывании?Я не могу это успокоить - PullRequest
0 голосов
/ 27 января 2019

У меня проблема с моим кодом.

scan-build of clang 8.0.0 выдает это предупреждение:

main.c:188:12: Out of bound memory access (access exceeds upper limit of memory block)
               putchar(tab[i][p]);
                       ^~~~~~~~~

Это интересующая функция:

void rysuj_glowny(int n)
{
    int nabs = abs(n);
    int size = 2 * nabs;

    if(size <= 0) return;

    char tab[size][size];

    rysowando(size, tab, nabs, n);

    for(int i = 0; i < size; i++)
    {
        for(int p = 0; p < size; p++)
        {
            putchar(tab[i][p]);
        }
        putchar('\n');
    }
}

Этот является целым кодом, если он необходим.

Эта функция получает значение 'n', создает двумерный массив с размерами [2 * n, 2 * n], заполняет массив с помощью другой функции (называемой 'rysowando') и затем печатает массив.

Я пытался подавить предупреждение с помощью различных условных выражений (таких как проверка 'size' и 'n' для различныхпредельные значения), но предупреждение все еще остается.Есть ли значение 'n', когда мой код ломается?Спасибо за ваш вклад!

1 Ответ

0 голосов
/ 27 января 2019

Я думаю, что в этом случае статический анализатор не так. Я попробовал это с clang 9.0 и получил другой набор результатов, но они также выглядят неправильно. Если вы выполните список шагов, вы увидите, что чего-то не хватает:

/ Users / realdarrin / Development / CodeReviewTester / CodeReviewTester / main.c: 202: 13: предупреждение: 1-й аргумент вызова функции является неинициализированным значением

       putchar(tab[i][p]);
        ^~~~~~~~~~~~~~~~~~

1 сгенерировано предупреждение.

Если вы выполните шаги, это даст:

main.c:213:20: Entering loop body
main.c:217:12: Assuming 'x' is equal to 1
main.c:217:22: Assuming the condition is false
main.c:217:35: Assuming the condition is false
main.c:222:12: Assuming the condition is false
main.c:213:5: Looping back to the head of the loop
main.c:213:20: Entering loop body
main.c:217:12: Assuming 'x' is equal to 1
main.c:217:22: Assuming the condition is false
main.c:217:35: Assuming the condition is false
main.c:222:12: Assuming the condition is false
main.c:213:5: Looping back to the head of the loop
main.c:213:20: Entering loop body
main.c:217:12: Assuming 'x' is equal to 1
main.c:217:22: Assuming the condition is false
main.c:217:35: Assuming the condition is false
main.c:222:12: Assuming the condition is false
main.c:213:5: Looping back to the head of the loop
main.c:213:20: Entering loop body
main.c:217:12: Assuming 'x' is equal to 1
main.c:217:22: Assuming the condition is false
main.c:217:35: Assuming the condition is false
main.c:222:12: Assuming the condition is true
main.c:226:20: Entering loop body
main.c:228:9: Calling 'rysuj_glowny'
main.c:187:1: Entered call from 'main'
main.c:192:8: Assuming 'size' is > 0
main.c:196:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysuj_glowny'
main.c:23:8: Assuming 'n' is not equal to 1
main.c:36:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysowando'
main.c:23:8: Assuming 'n' is not equal to 1
main.c:36:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysowando'
*main.c:23:8: Assuming 'n' is not equal to 1
main.c:45:8: Assuming 'startn' is <= 0
main.c:116:8: Assuming 'startn' is >= 0
main.c:36:5: Returning from 'rysowando'
main.c:36:5: Returning from 'rysowando'
main.c:196:5: Returning from 'rysowando'
main.c:198:20: Entering loop body
main.c:200:24: Entering loop body
main.c:200:9: Looping back to the head of the loop
main.c:200:24: Assuming 'p' is >= 'size'
main.c:198:5: Looping back to the head of the loop
main.c:206:1: Storing uninitialized value
main.c:228:9: Returning from 'rysuj_glowny'
main.c:226:5: Looping back to the head of the loop
main.c:226:20: Entering loop body
main.c:228:9: Calling 'rysuj_glowny'
main.c:187:1: Entered call from 'main'
main.c:192:8: Assuming 'size' is > 0
main.c:196:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysuj_glowny'
main.c:23:8: Assuming 'n' is not equal to 1
main.c:36:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysowando'
main.c:23:8: Assuming 'n' is not equal to 1
main.c:36:5: Calling 'rysowando'
main.c:20:1: Entered call from 'rysowando'
main.c:23:8: Assuming 'n' is equal to 1
main.c:26:29: Loop body executed 0 times
main.c:36:5: Returning from 'rysowando'
main.c:45:8: Assuming 'startn' is <= 0
main.c:116:8: Assuming 'startn' is >= 0
main.c:36:5: Returning from 'rysowando'
main.c:196:5: Returning from 'rysowando'
main.c:198:20: Entering loop body
main.c:200:24: Entering loop body
main.c:202:13: 1st function call argument is an uninitialized value

Я пометил одну строку звездочкой. Мне кажется, что отсутствует, что rysowando является рекурсивным в то время. Он говорит, что предполагает, что n не равно 1, но тогда не показывает рекурсию. Это сразу переходит к следующей строке.

Существуют и другие проблемы с анализом, например, когда n в конечном итоге равен 1, цикл внутри секции if (n == 1) выполняется 0 раз, даже если offset2 всегда равен offset + 1. Так что здесь со статическим анализатором что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...