Статичний аналіз коду (англ.static code analysis) — аналіз програмного забезпечення, який здійснюють (на відміну від динамічного аналізу) без реального виконання програм, що досліджуються. Зазвичай аналізу піддають початковий код, хоча іноді аналізу піддається об'єктний код, наприклад, P-код або код CIL. Термін зазвичай застосовують до аналізу, який проводить спеціальне програмне забезпечення (ПЗ), тоді як ручний аналіз називають «program understanding», «program comprehension» (розумінням або осягненням програми).
В залежності від використаного інструменту глибина аналізу може змінюватись від визначення поведінки окремих операторів до глобальнішого аналізу, що включає весь наявний вихідний код. Способи використання отриманої в ході аналізу інформації також різні — від виявлення місць, які можливо містять помилки (утиліти на кшталт Lint), до формальних методів, що дозволяють математично довести деякі властивості програми (наприклад, відповідність її поведінки до специфікації).
Деякі люди вважають програмні метрики і зворотне проектування формами статичного аналізу. Отримання метрик (англ.software quality objectives) та статичний аналіз часто поєднуються, особливо при створенні вбудованих систем.[1]
Статичний аналіз дедалі більше використовується у верифікації властивостей ПЗ, що використовується в комп'ютерних системах високої надійності, особливо критичних для життя (safety-critical[en]). Також застосовується для пошуку коду, що потенційно містить вразливості (іноді це застосування називається Static Application Security Testing, SAST).[2]
Статичний аналіз ПЗ постійно застосовується в наступних областях:
Для авіації (в комбінації з динамічним аналізом)[5]
За даними VDC на 2012 рік, приблизно 28 % розробників вбудованого ПЗ застосовували засоби статичного аналізу, а 39 % збирались почати їх використання протягом 2 років.[6]
Принципи статичного аналізу
Більшість компіляторів (наприклад, GNU C Compiler) виводять на екран «попередження» (англ.warnings) — повідомлення про те, що код, будучи синтаксично правильним, швидше за все, містить помилку. Наприклад:
intx;inty=x+2;// Змінну x не ініціалізовано!
Це найпростіший статичний аналіз. У компілятора є багато інших важливих характеристик — в першу чергу швидкість роботи і якість машинного коду, тому компілятори перевіряють код лише на очевидні помилки. Статичні аналізатори призначені для детальнішого дослідження.
Типи помилок, що виявляються статичними аналізаторами
Порушення алгоритму користування бібліотекою. Наприклад, для кожного fopen потрібен fclose. І якщо файлова змінна втрачається раніше, ніж файл закривається, аналізатор може повідомити про помилку.
Типові сценарії, що призводять до недокументованої поведінки. Стандартна бібліотека мови Сі відома великою кількістю невдалих технічних рішень. Деякі функції, наприклад, gets, в принципі небезпечні. sprintf і strcpy безпечні лише при певних умовах.
Переповнення буфера — коли комп'ютерна програма записує дані за межами виділеного в пам'яті буферу.
voiddoSomething(constchar*x){chars[40];sprintf(s,"[%s]",x);// sprintf в локальний буфер, можливе переповнення....}
Object*p=getObject();intpNum=reinterpret_cast<int>(p);// на x86-32 вірно, на x64 частину вказівника буде втрачено; потрібен intptr_t
Помилки у повторюваному коді. Багато програм виконують декілька разів один і той же код з різними аргументами. Зазвичай повторювані фрагменти не пишуть з нуля, а розмножують і виправляють.
dest.x=src.x+dx;dest.y=src.y+dx;// помилка, треба dy!
Помилки форматних рядків — у функціях на зразок printf можуть бути помилки з невідповідністю форматного рядка реальним типам параметрів.[7]
std::wstrings;printf("s is %s",s);
Незмінний параметр, що передається у функцію — ознака зміни вимог до програми. Коли-то параметр був задіяний, але зараз він вже не потрібен. В такому випадку програміст може взагалі позбутися цього параметра — і пов'язаної з ним логіки.
voiddoSomething(intn,boolflag)// flag завжди дорівнює true{if(flag){// якась логіка}else{// код є, але не задіяний}}doSomething(n,true);...doSomething(10,true);...doSomething(x.size(),true);
Інші помилки — багато функцій бібліотек не мають побічного ефекту, і виклик їх як процедур не має сенсу.[7]
std::strings;...s.empty();// код нічого не робить; ймовірно, ви хотіли s.clear()?
T-SQL Analyzer [Архівовано 8 серпня 2016 у Wayback Machine.] — інструмент, який може переглядати програмні модулі в базах даних під управлінням Microsoft SQL Server 2005 або 2008 і виявляти потенційні проблеми, пов'язані з низькою якістю коду.