Новачок-програміст засмучений відсутністю словника помилок компілятора


66

Друг моєї родини попросив мене трохи допомогти, коли він вчиться програмувати (мовою С). Поки ми говорили, він висловив розчарування з приводу того, що важко розуміє повідомлення про помилки, який дає його компілятор (GCC), коли робить помилки. Він не розуміє всіх вживаних термінів, а іноді саме їх поєднання виходить за межі його розуміння. Він запитував у мене: "Чому документація компілятора не містить більш довгих пояснень повідомлень про помилки?" - і я не мав гарної відповіді на нього.

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

Отже, як новачок-програміст повинен підійти до завдання розуміння повідомлень про помилки компілятора? Зокрема, з комбінацією C і GCC?


7
"Отже, як новачок-програміст повинен підійти до завдання розуміння повідомлень про помилки компілятора?" 1 / сарказм вимкнено. Це рідко виявляється недоліком або помилкою в компіляторі.
πάντα ῥεῖ

10
@MasonWheeler: Новачок часто не вибирає, який компілятор використовувати під час навчання. А GCC є загальним знаменником багатьох, багатьох систем ...
einpoklum

24
Якщо мова йде про помилки шаблону GCC C ++, я виявляю, що після припинення читання після "Помилка <файл: рядок>" та вивчення вихідних файлів, я вважаю, що помилка швидше, з додатковим побічним ефектом збереження моєї здоровості, ніж якщо я прочитаю фактичну помилку, яку дав GCC .....
mattnz

18
Рішення очевидно: Використовуйте компілятор з менш заплутаним результатом. Я пропоную rmcc . Він друкує Yes.або No.залежно від того, складений чи ні ваш код. Миттєво знімає розчарування від нерозуміння довгих і безглуздих повідомлень!
труба

21
C не є гарною мовою для початківців - і ви натрапили на одну з причин. При цьому, Кланг, як правило, пропонує набагато кращі помилки, які також можуть бути більш привабливими для початківців.
Теодорос Чатзіґянакікіс

Відповіді:


164

Кілька корисних прийомів:

  • Увімкніть -Wallі -Werror. Це може здатися протиінтуїтивним, коли ви боретеся з розшифровкою повідомлень про помилки, щоб створити ще більше повідомлень про помилки, але попередження, як правило, простіше зрозуміти та наблизити до фактичного джерела проблеми, і ігнорування їх може призвести до помилок, які важко зрозуміти .
  • Просто спробуйте виправити першу помилку у списку. Часто помилки складаються один з одним, що призводить до того, що пізніші повідомлення про помилки насправді не є фактичними помилками. Виправити один і перекомпілювати. Ви будете краще виправляти кілька повідомлень про помилки, коли отримаєте більше досвіду.
  • Використовуйте найновішу можливу версію компілятора. С - надзвичайно стійка мова. Тому величезна частина удосконалень новіших компіляторів полягає не в тому, щоб додати мовні функції, а поліпшити досвід розробника, включаючи кращі повідомлення про помилки. У багатьох широко використовуваних дистрибутивах Linux за замовчуванням є дуже старі версії gcc.
  • Програма поступово Не намагайтесь написати тонну коду перед тим, як компілювати. Напишіть найкоротшу можливу суму, яка все ще буде складена. Якщо ви змінили лише один рядок з моменту останнього чистого складання, зрозуміти, який рядок містить фактичну проблему, набагато простіше.
  • Напишіть одиничні тести. Це робить вас більш впевнено робити уточнюючі зміни рефакторингу під час виправлення помилок компіляції.

23
Хороший ІДЕ також може значно допомогти досвіду, наприклад, підкреслення помилок червоного кольору.
BlueRaja - Danny Pflughoeft

86
"Програмуйте поступово. Не намагайтеся написати тонну коду перед компіляцією. Напишіть найкоротший можливий обсяг, який все одно буде компілюватися. Якщо ви змінили лише один рядок з моменту останнього чистого складання, це зрозуміти набагато простіше який рядок містить фактичну проблему. " Це, стільки це. Також більшість IDE попередить вас, якщо ви будете писати код, який не буде компілюватися, та виділити помилки.
Полігном

4
@einpoklum: не варто недооцінювати третій варіант; Повідомлення про помилки компілятора значно покращилися. Аналогічно використовуйте кілька компіляторів (наприклад, gcc та clang) - виявляє більше помилок / попереджень, і один з них може мати кращу діагностику для певної проблеми, ніж інший.
Мат

19
@einpoklum: писати речі поступово дуже важливо , особливо для початківців. Гек, якщо ви вважаєте, що "короткі програми програмування" не можна виконувати поступово, розділивши їх на кілька невеликих функцій і реалізуючи та компілюючи їх по одному, вам слід спробувати вдосконалити цей навик для себе ..
Док Браун

4
Хитрість, яка допомогла мені: якщо у повідомленні про помилку згадується рядок N, перевірте рядок N-1. Наприклад, якщо вам не вистачає крапки з комою в рядку 17, повідомлення про помилку скаже, що щось не так із рядком 18. Це тому, що компілятор очікував крапки з комою, але отримав щось інше, у наступному рядку.
користувач2023861

56

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

Помилки компілятора C не настільки інтуїтивно зрозумілі, як, скажімо, помилки компілятора C #, з багатьох причин пов'язані з природою C. "близької до металу". Вирішення помилок компілятора в C не є вправою узгодження шаблону, тому що помилка ви отримання може не мати нічого спільного з реальною проблемою. На відміну від C # або Java, де повідомлення про помилку, як правило, відображає точне місце розташування коду та проблему, помилки в C, ймовірно, будуть численними і далеко не далеко.

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

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


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

18
По суті, так. Але практично це неможливо. Я цим займаюся дуже давно, і все одно отримую незрозумілі повідомлення про помилки компілятора щоразу, коли пишу програму C. Я рідко намагаюся читати ці повідомлення і намагаюся їх зрозуміти; натомість я дивлюся на те, куди вказується повідомлення про помилку, і оскільки я знаю, як має виглядати основна структура синтаксису програми C, я можу помітити проблему порівняно швидко, не витрачаючи часу на розшифровку повідомлень про помилки.
Роберт Харві

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

14
[знизує плечима] Якщо ви не використовуєте словник, щоб просто доповнити свої вже наявні знання англійської мови, я б запропонував, що ви робите це неправильно. Останнє, що я б запропонував, - це те, що змушує початківців програмістів зависати на лексиці більше, ніж вони є. Програмістам не потрібно більше слів; їм потрібно більше вміння.
Роберт Харві

13
@einpoklum, словник тут не допоможе. Опис слова "lvalue", ймовірно, може бути або надто технічним для початківця, або уздовж рядків "що може бути в лівій частині завдання", що так само не допомагає.
Барт ван Інген Шенау

26

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

Особливо це стосується найскладніших типів помилок. Наприклад, коли ви змішуєте дві подібні конструкції (незвичні для початківців), у компіляторів зазвичай виникає проблема з формуванням правильного повідомлення про помилку. Це може викликати плутанину, коли компілятор подає повідомлення про помилку щодо неправильного використання конструкції A, коли ви насправді задумали побудувати B. Другий компілятор може зробити висновок про те, що ви призначили B.


13

Хтось зробив спробу в словнику помилок GCC у Wikibooks деякий час тому, але, схоже, він ніколи не знімався і не оновлювався.

Розділ "Помилки" набагато далі, ніж розділ "Попередження". Схоже, це було націлене на G ++, але там, ймовірно, є якась корисна інформація для вашого друга.


12

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

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

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


1
Я не думаю, що було б докладно працювати. Крім того, до нього можна додати громадськість, як-от Stackoverflow або Wiki, довіреним людям, які мають дозволи редактора.
einpoklum

6
@einpoklum Ви коли-небудь бачили документи PHP? Ось що відбувається, коли ви дозволите громаді подбати про ці речі.
Кевін

4
Колись опубліковані (друковані) посібники були єдиним доступним ресурсом. Зазвичай вони були достатньо добре написані, щоб надати необхідну інформацію / керівництво для вирішення проблеми. З розвитком Інтернету ніхто більше не публікує друк (якщо він взагалі є онлайн). Якість "офіційного" довідкового матеріалу (он-лайн чи іншим способом) значно знизилася протягом десятиліть, які я програмував, тому найкращим доступним ресурсом часто є Google, а найкорисніші результати часто виявляються в Stackoverflow.
Zenilogix

2
Навіть якщо глосарій дійсно існує, пошукові системи можуть бути кращим способом доступу до них. Вони також корисні для виявлення, коли ви знаходитесь на незареєстрованій території: коли єдиним результатом пошуку є вихідний код, який визначає повідомлення про помилку;)
Warbo

2
У коледжі я одного разу отримав помилку компілятора: "Дейв не вважає, що це має статися. Будь ласка, напишіть йому електронну пошту за адресою <dave@example.com>". Я надіслав його по електронній пошті, і насправді я першим потрапив у цю конкретну помилку!
користувач1118321

6

Стандарт C використовує ряд термінів, таких як "lvalue" та "object" способами, відмінними від інших мов програмування, а повідомлення компілятора часто записуються такими термінами. Використання термінології суперечливо в деяких частинах Стандарту, але кожен, хто бажає вивчити С, повинен ознайомитись із проектами стандартів C89, C99 та / або C11, а також з обґрунтуванням документів, що їх містять. Пошук, наприклад, "проект C99" або "обгрунтування C89", повинен працювати досить добре, хоча вам може знадобитися переконатися, що ви отримаєте документ, який ви очікуєте. Хоча більшість компіляторів підтримує стандарт C99, може бути корисним знати, чим він відрізняється від стандарту C89, а обгрунтування C89 може запропонувати певну історичну основу, якої не мають більш пізні версії.


11
Стандарт C - це дуже щільний і важкий текст. У початківця немає шансів зрозуміти це.
NieDzejkob

4
@NieDzejkob: Термінологія, яка використовується компіляторами - і, як видається, йдеться про питання, - походить із стандарту. Хоча ви вірні, що частини Стандарту незрозумілі (частково тому, що він розроблений комітетом, і автори, здається, не мають послідовного розуміння того, що його частини мають означати), але кожен, хто хоче зрозуміти, що Такі терміни, як "lvalue", повинні знати про те, звідки вони походять. Далі, якщо хтось хоче зрозуміти, чому щось подібне x=0x1e-xпризводить до помилки, я насправді не знаю нічого, крім стандарту ...
supercat

3
Я згоден з @NieDzejkob: Стандарт C - це не той тип тексту, з яким ви хочете зіткнутися з новачком. Новачкам швидко потрібні позитивні практичні переживання . І їм потрібно вивчати нові речі по черзі, коли вони спливають. Читання стандарту або обгрунтування займає занадто багато часу, повністю перевантажуючи новичка інформацією.
cmaster

2
@cmaster: Я почав із стандарту C89 років тому, і це було не дуже погано навіть за дні, перш ніж браузери мали зручну функцію «знайти текст». Я визнаю, що пізніші стандарти стали гіршими та гіршими. Хоча ніхто не повинен покладатися на Стандарт як на єдину орієнтир, важливо визнати розбіжність між народною мудрістю щодо того, як поводяться компілятори мікрокомп'ютерів, і способами, що дозволяють стандарту поведінки низької якості поводитись, тому можна бути готовим, якщо він матиме боротися з останнім.
supercat

3
@cmaster: У будь-якому випадку, хтось, хто програмує C, повинен знати про Стандарт і знати, як проконсультуватися з ним, коли це потрібно, навіть якщо він не збирається прочитати всю справу. Якщо в Інтернеті виконується пошук стандартної функції бібліотеки, наприклад, можна знайти посилання, яке описує поведінку однієї програми в деяких кутових випадках, не зазначаючи, що, з точки зору стандарту, ці кутові випадки посилаються на Невизначене поведінку та інші можливості не працювати так само. Якщо замість цього шукати Стандарт, можна уникнути цієї проблеми.
supercat

5

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

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

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

З одного боку, більшість помилок, які може зробити новачок, можуть виявитись болісно очевидними для досвідченого програміста, не потребуючи допомоги компілятора. З іншого боку, вони набагато рідше стають настільки очевидними для новачків (хоча багато хто буде очевидним, більшість помилок - дурні помилки). На цьому етапі я повністю погоджуюся з Робертом Харві, новачкові просто потрібно ознайомитися з мовою. Цього не уникнути. Помилки компілятора, на які посилаються незнайомі поняття або здаються дивними, слід розглядати як підказку для поглиблення знань про мову. Аналогічно для випадків, коли компілятор скаржиться, але ви не можете зрозуміти, чому код неправильний.

Знову я погоджуюся з Робертом Харві, що потрібна краща стратегія використання помилок компілятора. Я окреслив деякі аспекти вище, і відповідь Роберта Харві дає інші аспекти. Навіть не зрозуміло, що сподівається твій друг зробити з таким «словником», і дуже малоймовірно, що такий «словник» насправді буде корисним твого друга. Повідомлення компілятора, безумовно, не є місцем для ознайомлення з поняттями мови 1, а «словник» - це не так вже й краще місце. Навіть з чітким описом того, що означає повідомлення про помилку, воно не збирається розповісти, як виправити проблему.

1 Декілька мов, як Elm і Dhall (і, можливо, Racket), а також кілька «орієнтованих на початківців» мов намагаються це зробити. У цьому сенсі поради MSalters щодо використання іншої реалізації є безпосередньо актуальними. Особисто я вважаю такі речі непереборними і не зовсім спрямовані на правильну проблему. Це не означає, що не існує способів покращення повідомлень про помилки, але, на мій погляд, вони мають тенденцію обертатися навколо того, щоб зрозуміти переконання компілятора та основу цих переконань.


4

Отже, як новачок-програміст повинен підійти до завдання розуміння повідомлень про помилки компілятора? Зокрема, з комбінацією C і GCC?

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

  • Видаліть / коментуйте код, який додали з моменту останньої успішної збірки.
  • Покладіть невеликі його частини назад і складіть
  • Повторюйте, поки помилка не з’явиться

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

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

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


4

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

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


1
Цей документ має надзвичайно важливу побічну перевагу, яку він може розмістити в Інтернеті (навіть якщо він містить лише 5-10 записів), і він буде чудовим диференціатором при подачі заявки на стажування.
Джош Румбут
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.