Як уникнути підводних каменів статичного аналізу


17

Я працюю в компанії, яка набрала б 11 тестів на Joel Test - принаймні на папері.

На практиці, однак, нічого не працює так добре, як очікувалося, і проект працює на DEFCON 1 вже півроку. Зараз більшість моїх однолітків раді, якщо вони можуть повернутися додому о 18:00 - у неділю.

Однією з мабуть хороших практик, яка вразила мене як непрацюючого, є використання інструментів статичного аналізу. Проект відстежує gcc -Wall попередження та фірмовий і дуже дорогий інструмент "C / C ++" .

Попередження Gcc роблять частіше, ніж не вказують на справжні (якщо більшу частину часу образливі) помилки.

Власні інструменти, однак, перераховують такі речі, як неявні касти та розміри в рядковому літералі. Неявні касти також перебувають у чорному списку в їх стилістиці.

Стандартна практика полягає в тому, що людей натискають, щоб закрити кожне попередження. Зауважте, що це не виключає попереджень, які є переважно помилковими, це не проблема.

Результат:

  1. Люди додають типи типів до кожного рейтингу та до кожного аргументу, що приховує реальні проблемні невідповідності в процесі.
  2. Люди вводять одні помилки або використовують іншу проблематичну мову (strlen замість sizeof, strncpy замість strcpy тощо)
  3. Попередження замовчуються.
  4. Звіти про помилки починають впроваджуватися.

Основна суть у тому, що оригінальний код працював і писав люди, які захищали свої мови, тоді як виправлення не були.

Зараз я не думаю, що цю компанію можна врятувати. Однак я хотів би знати, чи є кращий, бажано працюючий, спосіб використання інструментів "pro" або якщо я просто уникаю їх використання взагалі, якщо я буду приймати рішення в майбутньому.

Рішення, яке не передбачає всіх програмістів, - генії, які не можуть помилитися. Бо добре, якщо вони є, то не потрібно в першу чергу користуватися інструментами.


1
Побічна примітка: окрім «-Wall» GCC мають також опцію «-Wextra», та ще більше попереджень, які чомусь не включені в обидва метаоперації. Докладнішу інформацію див. У документах . Загалом, у кожному варіанті є згадка, якщо вона включена метаопцією. Отже, щоб знайти все, що не ввімкнено, ви можете виділити всі документи як слова «-Wall», так і «-Wextra», і ви побачите, що ще не використовується.
Привіт-Ангел

Додам також, що мені цікаво, що GCC не включила багато «-Wextra» у «-Wall». Повірте, деякі з цих прапорів надзвичайно корисні ; принаймні ці попередження звільняють мене від години налагодження.
Привіт-Ангел

1
Я здивований, що ніхто не згадав відгуки про коди у відповідях. Для мене люди, які намагаються прокрастися в якісь хитрі хаки, були б заблоковані кодовими відгуками ...
dyesdyes

Відповіді:


16

На практиці, однак, нічого не працює так добре, як очікувалося, і проект працює на DEFCON 1 вже півроку. Зараз більшість моїх однолітків раді, якщо вони можуть повернутися додому о 18:00 - у неділю.

Це, безумовно, хороший фрагмент вашої проблеми. Програмний інженер не може продуктивно працювати більше 40 годин на тиждень. Якщо ви переходите вище, ви завдаєте серйозної шкоди своїй працездатності - до того моменту, коли навіть робота 80 годин на тиждень приносить дуже мало значення для проекту, а іноді проекти можуть навіть регресувати, оскільки команда вводить більше помилок, ніж вони можуть виправити. Якщо ви робите 60 годин на тиждень і більше протягом півроку, то всій вашій команді потрібна хороша довга перерва і повернутися з 40 годин на тиждень. Ви не можете вирішити що - або з робочою силою , яка навряд чи здатна прочухана на клавіатурі , тому що вони так перевантажені роботою.

Власні інструменти, однак, перераховують такі речі, як неявні касти та розміри в рядковому літералі. Неявні касти також перебувають у чорному списку в їх стилістиці.

Вам дійсно потрібно або просто кинути інструмент цілком, або налаштувати / замінити його. Попередження про кожен неявний виступ є занадто великим, щоб хтось мав справу.


Не могли б ви надати посилання на дослідження, що становить приблизно 40 годин на тиждень?

11
тут і тут , лише для початку. Надзвичайно добре зафіксовано, що ви не можете робити більше 40 годин на тиждень продуктивної роботи. Простий Google знайде вам номери статей.
DeadMG

5
Дві невеликі, але важливі корективи ІМХО: обмеження 40 годин на тиждень - це приблизно приблизне середнє значення, і правило застосовується лише для тривалих періодів часу. Це нормально, щоб команда поставила додаткові години до важливого терміну, а потім відновилася (можливо, навіть взявши кілька вихідних днів). Також межа обмежується між людьми та з часом - одні можуть працювати 43 години на тиждень без проблем, інші - лише 35, а один - більш продуктивний на деякі тижні, ніж інші. Однак укладення значних понаднормових робіт більше ніж кілька тижнів поспіль справді спричинить серйозні проблеми.
Péter Török

13

Я працюю в компанії, яка набрала б 11 тестів на Joel Test - принаймні на папері.

Цей тест є м'яко стосується програмних компаній. Я не розумію галасу з цього приводу. Ви можете набрати 12, і все ще мати 100% програмістів. Люди мають значення набагато більше, ніж інструменти.

Власні інструменти, однак, перераховують такі речі, як неявні касти та розміри в рядковому літералі. Неявні касти також перебувають у чорному списку в їх стилістиці. Стандартна практика полягає в тому, що людей натискають, щоб закрити кожне попередження. Зауважте, що це не виключає попереджень, які є переважно помилковими, це не проблема.

Це найбільша проблема у всіх статичних аналізаторах: занадто багато помилкових спрацьовувань. Тільки спосіб впоратися з цим, щоб детально дізнатися , чому цей інструмент був створений , щоб дати попередження для певного питання. Тільки тоді ви зможете зробити кваліфіковані припущення щодо того, чи є попередження помилковим чи ні.

Для конкретного амплітуду неявних типкастів він існує через деякі дуже поширені, тонкі та небезпечні помилки на мові С, викликані двома (дебільними) неявними правилами просування типу C. Вони формально відомі як цілі правила просування та звичайні арифметичні перетворення . Я думаю, що менше одного десятого з усіх професійних програмістів на C може пояснити, що ці два правила роблять, а що вони не роблять. І все ж ці правила є надзвичайно фундаментальними і застосовуються тисячі разів між рядками в будь-якій звичайній програмі С.

Стандарт MISRA-C присвятив цілу главу, щоб пояснити ці небезпечні неявні правила перетворення, а потім вони додали численні досить складні правила, як уникнути помилок, викликаних неявною конверсією. Це мало певний вплив на всі статичні аналізатори на ринку.

Я рекомендую будь-якому програмісту C прочитати цю главу MISRA-C, або, принаймні, Google, два правила просування, про які я згадав, і прочитати про них якнайбільше. Ви можете ігнорувати статичний аналізатор лише тоді, коли знаєте все, що потрібно знати про ці правила.

Зараз я не думаю, що цю компанію можна врятувати. Однак я хотів би знати, чи є кращий, бажано працюючий, спосіб використання інструментів "pro" або якщо я просто уникаю їх використання взагалі, якщо я буду приймати рішення в майбутньому.

Рішення, яке не передбачає всіх програмістів, - генії, які не можуть помилитися. Бо добре, якщо вони є, то не потрібно в першу чергу користуватися інструментами.

Немає простого шляху. Справжня проблема - насправді не інструмент, а незрозуміла мова С. На короткий погляд це може здатися легкою мовою, але між рядками існує безліч нелогічних і дивних механізмів. І також є сотні випадків не визначеної / не визначеної / конкретної поведінки в мові. Більшість з них ви повинні навчитися і уникати.

Отже, ви або повинні стати ветеранським програмістом, який розуміє всі ці незрозумілі попередження, або ви повинні бути в команді, що має хоча б одну таку людину. Компанії, які наймають лише купу молодших програмістів без ветерана в колективі, не повинні використовувати ці інструменти, а також не працювати з розробкою програмного забезпечення високої цілісності.


Я взяв тест із щіпкою солі з самого початку, але це не інструмент для тестування програмістів, а інструмент для тестування роботодавців. Я думаю, ви могли б включити спритних колег як "кращі інструменти, які гроші можуть заплатити". І я приймаю вашу відповідь, щоб викинути інструменти SA та найняти та / або тренуватися краще. Колишній пункт, здається, є загальним знаменником.

@qpr Не перевіряє і роботодавця, просто готовність роботодавця витрачати гроші на розробку програмного забезпечення. Такі речі, як процедура прийняття на роботу, корпоративні цілі, знання ринку тощо, не згадуються. Я думаю, що більшість компаній «ІТ-бульбашки» на цьому тесті отримають 12 балів, при цьому керівництво, яке навіть не знає, які продукти розробляються, чи взагалі є ринок для них.

4

Незрозуміло, чи питаєте ви, як виправити проблему, чи як ви могли її уникнути в першу чергу. Я припускаю останнє.

Здається, ви покладалися на статичний аналіз як основний засіб виявлення та уникнення помилок. Можливо, вам краще було б більше зосередитись на одиничних тестах та динамічних інструментах ... таких як шашки пам'яті.

Дуже погано покладатися на інструмент, який генерує безліч помилкових позитивів, особливо якщо ви не можете придушити ці помилкові позитиви. Це заохочує втомлених / перевтомлених (або ледачих) програмістів робити "виправлення", щоб попередження відпадали. Якщо ви не можете вибірково придушити помилкові позитиви (наприклад, за допомогою коментарів) або налаштувати набір правил, тоді вам потрібен кращий інструмент. Або, принаймні, використовувати його потрібно лише ощадливо.

Це здається, що у вас є проблеми з тим, що люди недбалі та / або роблять помилки через непосильну роботу. Можливо, вам слід було б витратити більше часу / зусиль на перегляд коду. Це безпосередньо стосується вашого спостереження, що програмісти не є геніями.

Нарешті, це здається, що, можливо, ви страждали в нереальні терміни, погані люди, які потребують ресурсів та / або змінюють вимоги. Це проблема управління, і її потрібно вирішити на цьому рівні ... інакше існує значно підвищений ризик провалу проекту та довгострокового збитку для продуктивності та морального стану персоналу.


3

На додаток до відмінної відповіді user29079, я хотів би додати ще один недолік мови С, що додає до проблеми. Я не знав цього недоліку, поки не перейшов на Java.

Мета попередження - донести до відома письменника та майбутніх читачів кодексу факт, що відбувається щось рибне. Це, як концепція, цілком добре: чим більше попереджень ви включили, тим більше рибних речей ви відкриєте.

Що не так , це уявлення про те, що кожну маленьку рибку потрібно виправити за будь-яку ціну, змінивши код . Саме це і спричинило проблему, яку описує ОП: спроби, що збиваються, поспішно роблять попередження, відходять, змінюючи код, який працює чудово.

У той же час, ми не хочемо, щоб наш код щоразу виписував сотні попереджень під час компіляції, оскільки досить скоро попередження стають безглуздими, і ніхто більше не звертає уваги на нові попередження.

Отже, це здається випадком конфліктних цілей; протиріччя.

Дуже хорошим рішенням цієї, здавалося б, неможливої ​​проблеми є можливість вибіркового придушення певного попередження на основі заяви шляхом висловлювання, щоб ми могли придушити його саме там, де ми хочемо вказати, що ми дійсно знаємо, що робимо, без змінити будь-який код.

У Java є гарне рішення цього питання з @SuppressWarnings( "" )анотацією. Якщо ви робите, скажімо, так звану неперевірену конверсію в java, компілятор видає попередження, щоб донести це до вашої уваги, ви її вивчите, ви визначите, що це ще один із тих випадків, коли ви знаєте, що ви робите, значить, ви передуєте заяві, що ображає, @SuppressWarnings( "unchecked" )анотацію, яка зачіпає лише твердження, яке негайно слідує за нею, і ви продовжуєте своє життя.

Отже, попередження відходить, код залишається незмінним, а анотація придушення стоїть там, пофарбована зеленим кольором за допомогою підкреслення синтаксису, щоб зафіксувати факт, що відбувається перетворення iffy, але автор обіцяє, що це добре. (*) Усі щасливі.

У Java ви можете навіть приєднати окремі параметри до функцій @SuppressWarnings(), щоб відключити певне попередження, яке може видаватися лише для цього конкретного параметра.

Однак, наскільки я знаю, C ніколи не підтримував жодного стандартного механізму вибіркового придушення попереджень про висловлювання, а деякі компілятори, які реалізували власні власні механізми, робили це чітко, наприклад #pragma warning (nnn:N)директиви Microsoft C. Проблема з цими директивами полягає в тому, що вам потрібні два рядки директив для того, щоб придушити попередження для одного оператора і залишити це попередження включеним для наступних операторів. Таким чином, програмісти на C малоймовірно, що вони перейдуть до звички придушувати попередження на основі окремої заяви, навіть коли вони знають, що це конкретне попередження щодо даного твердження добре.


(*) хтось може заперечити, що якщо ви дозволите це, то кожен програміст в будинку буде придушувати попередження, не даючи їм жодної думки; відповідь на це полягає в тому, що ви можете зробити все можливе, щоб допомогти програмістам виконати свою роботу краще, але ви нічого не можете зробити, якщо вони активно вирішать вас саботувати.


Іншими словами, хоча зміна джерела з метою видалення кожного останнього попередження є ключовою умовою належної практики, зміна компільованого коду не є, оскільки це усуває прямий код, який просто правильний без поважних причин. Хороша відмінність.
Натан Туггі

2

Я б сказав (не знаючи деталей), що ваша компанія допустила більш значні помилки, і це лише симптом: не вдалося правильно визначити домен виробленого програмного забезпечення, правильно керувати командою та визначити розумні цілі.

Якщо програмне забезпечення, яке пише ваша команда, є критичним, від чого залежить людське життя, інструменти статичного аналізу є важливими та корисними. Оскільки «вартість» помилки, виміряна грошима (ігноруючи, наскільки це цинічно), є високою, для роботи існують спеціальні інструменти. Існують рекомендації як для C, так і для C ++ щодо безпечного використання мовних функцій (прочитайте, чого слід уникати та як далеко пройти, щоб уникнути цього).
Однак у такій ситуації, коли працівники працюють у неділю, це дуже погана ідея. Більше того, з контексту, який ви надали, я екстраполюю, що неохайна робота не є рідкісною. Тож якщо це так, проблема дуже- дужевеликий, і ваше керівництво намагається вирішити це за допомогою «кращих» інструментів. На жаль, так не працює. Якщо я навіть близький до корекції, я б підказав, що ви почнете шукати іншу роботу. Критично важливе для місії програмне забезпечення - це щось, що може переслідувати вас і зруйнувати вашу професійну репутацію, не кажучи вже про перспективи судових процесів.

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

Якщо вам потрібно керувати командою програмного забезпечення, яка пише якийсь код C або C ++, я б сказав, спочатку визначте, які основні цілі проекту. Якщо написання коду без помилок має надзвичайно важливе значення (наприклад, новий надзвичайний соціальний додаток для iOS та Android не підходить для цього), тоді використовуйте статичний аналіз, можливо, навіть далеко до формальної специфікації та офіційної перевірки. Але якщо це так, вибирати хороших програмістів і змусити їх працювати в розумному середовищі з адекватним навантаженням та належним 40-годинним тижнем набагато важливіше.

Люди не можуть працювати відповідально, якщо до них ставляться як до рабів (а хтось, хто займає мої канікули, саме це), а хороші програмісти просто відмовляться це робити регулярно, якщо вони не знають нічого кращого (і якщо вони хороші, шанси є вони роблять).

Підсумок: Визначте свої цілі, а потім визначте інструменти та процес, який ви використовуєте, не дозволяйте доступним інструментам визначати процес (ерго цілі), оскільки (погане) управління може захотіти вас змусити.


1

Як зазначено у відповіді k.steff, інструменти статичного аналізу для "C" корисні, якщо ви будуєте програмне забезпечення в критичній ситуації (програмне забезпечення літака), і їх потрібно використовувати з першого дня (не після місяців розробки, коли виникає невідтворювана помилка ).

Використання подібних інструментів пізно в процесі розробки зазвичай є ознакою поганого вибору дизайну на початку процесу.

У некритичному програмному забезпеченні такі інструменти корисні для:
-забезпечення управління, для того, щоб вони почували себе корисними (ми щось зробили, ми витратили багато грошей на виправлення програмного забезпечення). Це дає їм дії, які легко виконати у своїх звітах Powerpoint).
-Зберігайте "токсичних" розробників зайнятими. Дозвольте їм налаштувати інструмент та проаналізувати результати інструменту, щоб ви могли встигнути виправити їхні неприємні помилки.
правила примусового кодування. У такому випадку його потрібно використовувати з першого дня. Але кращим вибором може бути хороший інструмент перегляду коду.

Тож, на мою думку, ви повинні уникати подібних дорогих, трудомістких інструментів або використовувати їх, щоб не зайняти "токсичних" людей.


1

Я працюю в компанії, яка набрала б 11 тестів на Joel Test - принаймні на папері.

Валідація тестом Джоеля - це не міра передового досвіду; Недійсність тесту Джоеля є мірою поганих / відсутніх практик. Іншими словами, це можна розглядати як необхідне, але недостатнє.

Зараз більшість моїх однолітків раді, якщо вони можуть повернутися додому о 18:00 - у неділю.

Схоже, у вас проблеми з управлінням. Систематичний понаднормовий час не є рішенням для того, щоб робити справи; якщо що-небудь, це рішення зробити так, щоб речі виглядали так, як вони працюють і накопичують технічну заборгованість.

Зараз я не думаю, що цю компанію можна врятувати. Однак я хотів би знати, чи є кращий, бажано працюючий, спосіб використання інструментів "pro" або якщо я просто уникаю їх використання взагалі, якщо я буду приймати рішення в майбутньому.

Так, є спосіб використовувати статичний аналіз коду в розумному порядку.

Вони можуть, і зазвичай, надають велику цінність. Вам просто потрібно пам’ятати, що (як попередження компілятора) інструмент статичного аналізу може (максимум) дати підказки, що щось піде не так - не звіти про помилки, а також ніякої впевненості.

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

Неявні касти також перебувають у чорному списку в їх стилістиці.

Це звучить як проблема компетентності управління, а не проблема статичного аналізу.

Результат:

Люди додають типи типів до кожного рейтингу та до кожного аргументу, що приховує реальні проблемні невідповідності в процесі.

Люди вводять одні помилки або використовують іншу проблематичну мову (strlen замість sizeof, strncpy замість strcpy тощо)

Попередження замовчуються.

Звіти про помилки починають впроваджуватися.

Все це способи зробити так, щоб періодичні звіти виглядали добре, а не способи виправити проблеми в коді (схоже, у вас знову проблема з компетенцією управління).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.