Я часто чую, що при компілюванні програм C і C ++ я повинен "завжди включати попередження компілятора". Чому це потрібно? Як це зробити?
Іноді я також чую, що я повинен "трактувати попередження як помилки". Повинен я? Як це зробити?
Я часто чую, що при компілюванні програм C і C ++ я повинен "завжди включати попередження компілятора". Чому це потрібно? Як це зробити?
Іноді я також чую, що я повинен "трактувати попередження як помилки". Повинен я? Як це зробити?
Відповіді:
Компілятори C і C ++, як відомо, погано повідомляють про деякі поширені помилки програміста за замовчуванням , такі як:
return
значення з функціїprintf
і scanf
сім'ях, що не відповідають рядку форматуВони можуть бути виявлені та повідомлені, як правило, зазвичай не за замовчуванням; цю функцію потрібно чітко запитати за допомогою параметрів компілятора.
Це залежить від вашого компілятора.
Microsoft C і C ++ компілятори розуміти перемикачі подобається /W1
, /W2
, /W3
, /W4
і /Wall
. Використовуйте принаймні /W3
. /W4
і /Wall
може надсилати помилкові попередження для файлів заголовків системи, але якщо ваш проект чисто компілюється з одним із цих параметрів, перейдіть до цього. Ці варіанти взаємовиключні.
Більшість інших компіляторів розуміють такі опції , як -Wall
, -Wpedantic
і -Wextra
. -Wall
є важливим, а всі інші рекомендуються (зауважте, що, незважаючи на свою назву, вони -Wall
вмикають лише найважливіші попередження, не всі ). Ці параметри можна використовувати окремо або всі разом.
У вашого IDE може бути спосіб включити їх через користувальницький інтерфейс.
Попередження компілятора сигналізує про потенційно серйозну проблему у вашому коді. Перераховані вище проблеми майже завжди є фатальними; інші можуть бути, а можуть і не бути, але ви хочете, щоб компіляція не вдалася, навіть якщо це виявиться помилковою тривогою. Вивчіть кожне попередження, знайдіть першопричину та виправте її. У випадку помилкової тривоги обійдіть її - тобто використовуйте іншу мовну функцію або побудуйте так, щоб попередження більше не спрацьовувало. Якщо це виявляється дуже важким, відключіть це особливе попередження в кожному конкретному випадку.
Ви не хочете залишати попередження як попередження, навіть якщо всі вони є помилковими тривогами. Це може бути добре для дуже малих проектів, де загальна кількість випущених попереджень становить менше 7. Що б то не було, і нове попередження легко загубитися в потопі старих знайомих. Не дозволяйте цього. Просто змусьте весь ваш проект чисто скластися.
Зверніть увагу, це стосується розробки програм. Якщо ви випускаєте свій проект у світ у вихідній формі, то може бути непоганою ідеєю не постачати -Werror
або еквівалент у звільненому сценарії збірки. Люди можуть спробувати створити ваш проект за допомогою іншої версії компілятора або з іншим компілятором, який може мати інший набір попереджень. Ви можете хотіти, щоб їхня побудова була успішною. Це все-таки хороша ідея, щоб попередження були включені, щоб люди, які бачать попереджувальні повідомлення, могли надсилати вам повідомлення про помилки чи виправлення.
Це знову робиться за допомогою перемикачів компілятора. /WX
для Microsoft, більшість інших використовують -Werror
. У будь-якому випадку компіляція не вдасться, якщо є якісь попередження.
C, як відомо, є досить низьким рівнем мови, як це стосується HLL. C ++, хоча це може здатися значно вищим рівнем мови, ніж C, все ж поділяє низку його рис. І однією з таких рис є те, що мови були розроблені програмістами, для програмістів - і, зокрема, програмістів, які знали, що роблять.
[Що стосується решти цієї відповіді, я збираюся зосередитись на C. Більшість того, що я скажу, також стосується C ++, хоча, можливо, не так сильно. Хоча, як чудово говорив Б'ярн Струструп, "C полегшує себе стріляти в ногу; C ++ робить це важче, але коли ви це робите, це відбиває всю ногу". ]
Якщо ви знаєте, чим займаєтесь - дійсно знаєте, що робите - іноді, можливо, доведеться «порушувати правила». Але більшість часу більшість із нас погоджуються, що цілеспрямовані правила не дають нам усіх проблем, і що мимоволі порушувати ці правила - це погана ідея.
Але в C і C ++ є надзвичайно велика кількість речей, які ви можете зробити - це "погані ідеї", але формально не "проти правил". Іноді вони погано уявляють деякий час (але можуть бути захисні в інший час); іноді вони погана ідея практично весь час. Але традицією завжди було не попереджати про ці речі - адже, знову ж таки, припущення полягає в тому, що програмісти знають, що вони роблять, вони б не робили цього без поважних причин, їх би роздратувала купа зайвих попереджень
Але, звичайно, не всі програмісти дійсно знають, що роблять. І, зокрема, кожен програміст на C (незалежно від того, наскільки досвідчений) проходить фазу свого початкового програміста на C. І навіть досвідчені програмісти C можуть недбало і помилитися.
Нарешті, досвід показав не лише те, що програмісти роблять помилки, але й що ці помилки можуть мати реальні, серйозні наслідки. Якщо ви помилитесь, і компілятор не попередить вас про це, і чомусь програма не відразу виходить з ладу або робить щось очевидно неправильне через це, помилка може ховатися там, прихована, іноді роками, поки це не спричинить дійсно велика проблема.
Так виходить, що, здебільшого, попередження - це гарна ідея. Навіть досвідчені програмісти дізналися (насправді це " особливо досвідчені програмісти навчилися"), що, в цілому, попередження мають більше користі, ніж шкоди. Кожен раз, коли ви робили щось не так навмисно, і попередження викликало неприємність, мабуть, принаймні десять разів ви щось випадково зробили не так, і попередження врятувало вас від подальших неприємностей. І більшість попереджень можна вимкнути або вирішити за ті кілька разів, коли ви дійсно хочете зробити «неправильну» справу.
(Класичний приклад такої «помилка» є тестом if(a = b)
Великий частини часу, це помилка, тому більшість компіляторів цих днів попередять про це. -. Деякі навіть за замовчуванням Але якщо ви дійсно хотіли як правонаступник b
до a
і випробуванню в результаті ви можете відключити попередження, ввівши if((a = b))
.)
Друге питання: чому ви хочете попросити компілятора розглянути попередження як помилки? Я б сказав, що це через людську природу, зокрема, надто легку реакцію сказати: «О, це просто попередження, це не так важливо, я прибираю це пізніше». Але якщо ви прокрастінатор (і я не знаю про вас, але я жахливий прокрастінатор), легко відкласти обов’язково очищення в основному коли-небудь - і якщо ви ввійдете в звичку ігнорувати попередження, це стає простіше і простіше пропустити важливе попереджувальне повідомлення, яке сидить там непомітно, посеред усіх тих, кого ви ігноруєте.
Тому просити компілятора ставитися до попереджень як до помилок - це невелика хитрість, яку ви можете зіграти на собі, щоб обійти цю людську підданість.
Особисто я не так наполегливо ставлюсь до попереджень, як до помилок. (Насправді, якщо я чесний, я можу сказати, що я практично ніколи не вмикаю цей варіант у своєму "особистому" програмуванні.) Але ви можете бути впевнені, що цей параметр увімкнено на роботі, де наш посібник зі стилів (який я писав) мандат його використання. І я б сказав - я підозрюю, що більшість професійних програмістів скажуть - що будь-який магазин, який не трактує попередження як помилки в C, поводиться безвідповідально, не дотримується загальноприйнятих найкращих галузевих практик.
if(a = b)
, тому нам не потрібно попереджати про це". (Тоді хтось створює список 10 критичних помилок у 10 випущених продуктах, які є наслідком цієї конкретної помилки.) "Гаразд, жоден досвідчений програміст C ніколи цього не напише ..."
if (returnCodeFromFoo = foo(bar))
і мати на увазі, щоб захопити і протестувати код в одному місці (припустимо, єдиною метою foo
є наявність побічних ефектів!) Те, що дійсно досвідчений програміст може знати, це не хороший стиль кодування знаходиться поруч із точкою;)
if (returnCodeFromFoo = foo(bar))
, тоді вони додають коментар і вимикають попередження (так що, коли програміст з технічного обслуговування перегляне це через 4 роки, він / вона зрозуміє, що код навмисний. Це сказав, я працював з тим, хто в (на землі Microsoft C ++) наполягав на тому, що поєднання / Стіна з поводженням з попередженнями як помилками - це шлях. Ага, це не так (якщо ви не хочете вносити багато коментарів щодо придушення).
Попередження складаються з найкращих порад, які деякі з найкваліфікованіших розробників C ++ можуть використати у програмі. Їх варто тримати навколо.
C ++, будучи повною мовою Тюрінга, має безліч випадків, коли компілятор повинен просто довіряти тому, що ви знали, що робите. Однак є багато випадків, коли компілятор може зрозуміти, що ви, мабуть, не мали наміру писати те, що ви написали. Класичний приклад - це коди printf (), які не відповідають аргументам, або std :: рядки, передані printf (не те, що коли-небудь трапляється зі мною!). У цих випадках написаний вами код не є помилкою. Це дійсний вираз C ++ з коректною інтерпретацією для компілятора, на який потрібно діяти. Але компілятор має сильну думку, що ви просто не помітили те, що легко знайти сучасний компілятор. Це попередження. Вони є очевидними для компілятора, використовуючи всі суворі правила C ++, які є в його розпорядженні, і які ви могли не помітити.
Вимкнути попередження або ігнорувати їх - це як вибрати вибір ігнорувати безкоштовні поради у тих кваліфікованіших, ніж ви. Це урок huberis, який закінчується, коли ви летите занадто близько до сонця і крила тануть, або виникає помилка пошкодження пам’яті. Між двома, я прийму падіння з неба будь-якого дня!
"Трактуйте попередження як помилки" - це крайня версія цієї філософії. Ідея тут полягає в тому, щоб ви вирішили кожне попередження, яке вам дає компілятор - ви слухаєте кожну частину безкоштовних порад і дієте на неї. Чи буде це для вас хорошою моделлю для розвитку, залежить від команди та над тим, над яким продуктом ви працюєте. Це подвижницький підхід, який може мати монах. Для деяких це чудово працює. Для інших це не так.
У багатьох моїх програмах ми не трактуємо попередження як помилки. Це робимо тому, що ці конкретні програми потрібно компілювати на декількох платформах з кількома компіляторами різного віку. Іноді ми знаходимо, що насправді неможливо виправити попередження на одній стороні, не перетворившись на попередження на іншій платформі. Тож ми просто обережні. Ми поважаємо попередження, але не перегинаємо їх назад.
equals
/ hashCode
), і це питання якості впровадження, про які з них повідомляється.
Мало того, що обробка попереджень робить кращий код, це робить вас кращим програмістом. Попередження розповідатимуть вам про речі, які сьогодні можуть здатися вам мало, але одного дня ця погана звичка повернеться і відкусить вашу голову.
Використовуйте правильний тип, поверніть це значення, оцініть це повернене значення. Знайдіть час і поміркуйте: "Чи справді це правильний тип у цьому контексті?" "Чи потрібно мені це повернути?" І біггі; "Чи буде цей код переносним протягом наступних 10 років?"
Увійдіть у звичку писати в першу чергу код без попередження.
Інші відповіді чудові, і я не хочу повторювати те, що вони сказали.
Ще один аспект "чому вмикати попередження", який не був належним чином торкнувся, - це те, що вони дуже допомагають у підтримці коду. Коли ви пишете програму значних розмірів, неможливо одразу тримати всю річ у голові. У вас зазвичай є функція або три, про які ви активно пишете і думаєте, і, можливо, файл або три на вашому екрані, на який ви можете посилатися, але основна частина програми існує десь у фоновому режимі, і ви повинні вірити, що це продовжує працювати.
Попередження про те, щоб вони були максимально енергійними та в обличчі, допомагають попередити вас про те, що щось, що ви змінили, спричинить неполадки у тому, що ви не можете бачити.
Візьмемо для прикладу попередження про стукіт -Wswitch-enum
. Це викликає попередження, якщо ви використовуєте перемикач на enum і пропускаєте одне з можливих значень enum. Ви можете подумати, що це було б малоймовірною помилкою: ви, мабуть, принаймні придивились до переліку значень перерахунків, коли ви писали заяву перемикача. Можливо, у вас навіть є IDE, який створив для вас параметри комутації, не залишаючи місця для людських помилок.
Це попередження дійсно стає власним, коли через півроку ви додасте ще один можливий запис до перерахунків. Знову ж таки, якщо ви думаєте про код, про який йдеться, ви, мабуть, будете добре. Але якщо цей перелік використовується для декількох різних цілей, і це одна з тих, кому потрібна додаткова опція, дуже просто забути оновити комутатор у файлі, якого ви не торкалися протягом 6 місяців.
Ви можете придумувати попередження так само, як ви думали про автоматизовані тестові випадки: вони допомагають вам переконатися, що код розумний, і робити те, що вам потрібно, коли ви його вперше пишете, але вони ще більше допомагають переконатися, що це продовжує робити те, що вам потрібно, поки ви робите це. Різниця полягає в тому, що тестові випадки працюють дуже вузько до вимог вашого коду, і ви повинні їх писати, тоді як попередження працюють широко до розумних стандартів майже для всього коду, і вони дуже щедро постачаються гномами, які складають компілятори.
Наприклад, налагодження помилки сегментації вимагає від програміста відстежувати корінь (причину) помилки, яка зазвичай знаходиться в попередньому місці у вашому коді, ніж рядок, який врешті-решт спричинив помилку сегментації.
Дуже типово, що причина - це рядок, для якого компілятор випустив попередження, яке ви проігнорували, і рядок, який викликав помилку сегментації, рядок, який врешті-решт викинув помилку.
Виправлення попередження призводить до усунення проблеми .. Класика!
Демонстрація сказаного. Розглянемо наступний код:
#include <stdio.h>
int main(void) {
char* str = "Hello world!";
int idx;
// Colossal amount of code here, irrelevant to 'idx'
printf("%c\n", str[idx]);
return 0;
}
який при компілюванні з прапором "Wextra" передається GCC, дає:
main.c: In function 'main':
main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
9 | printf("%c\n", str[idx]);
| ^
який я міг ігнорувати і виконувати код у будь-якому випадку .. І тоді я став свідком "великої" помилки сегментації, як говорив мій професор епікуру ІР:
Помилка сегментації
Щоб налагодити це в реальному сценарії, слід почати з лінії, яка викликає помилку сегментації, і спробувати простежити, що є коренем причини. Їм доведеться шукати, що трапилося з цією колосальною сумою i
і str
всередині неї. коду там ...
Поки, одного разу, вони опинилися в ситуації, коли виявляють, що idx
використовується неініціалізоване, таким чином, воно має значення сміття, що призводить до індексації рядка (способу) поза його межами, що призводить до помилки сегментації.
Якби вони не ігнорували попередження, вони знайшли б помилку негайно!
str[idx]
" не "Добре, де str
і idx
визначено?"
idx
ви отримаєте значення, яке ви очікували на своєму тесті (не надто малоймовірно, якщо очікуване значення дорівнює 0), і насправді трапляються вказівки на деякі конфіденційні дані, які ніколи не слід друкувати при розгортанні.
Трактувати попередження як помилки - це лише засіб самодисципліни: ви складали програму для перевірки цієї блискучої нової функції, але ви не можете, поки не виправите неохайні частини. Додаткової інформації немає Werror
, вона просто чітко визначає пріоритети:
Не додайте новий код, поки ви не усунете проблеми в існуючому коді
Це дійсно важливий спосіб мислення, а не інструменти. Вихід діагностики компілятора - це інструмент. MISRA (для вбудованого C) - ще один інструмент. Не має значення, який саме ви використовуєте, але, мабуть, попередження компілятора - це найпростіший інструмент, який ви можете отримати (це лише один прапор, який потрібно встановити), а співвідношення сигнал / шум дуже високе. Тож немає причин не використовувати його.
Жоден інструмент не є непогрішним. Якщо ви пишете const float pi = 3.14;
, більшість інструментів не скажуть вам, що ви визначили π з поганою точністю, що може призвести до проблем на дорозі. Більшість інструментів не піднімуть брови if(tmp < 42)
, навіть якщо загальновідомо, що введення змінних безглуздих імен та використання магічних чисел - це спосіб катастрофи у великих проектах. Ви повинні розуміти, що будь-який код "швидкого тестування", який ви пишете, - це саме тест, і ви повинні правильно його отримати, перш ніж переходити до інших завдань, поки ви все ще бачите його недоліки. Якщо ви залишите ці коди такими, які є, налагодження, якщо після того, як ви витратите два місяці на додавання нових функцій, буде значно складніше.
Після того, як ви ввійдете в правильний спосіб мислення, використовувати його немає сенсу Werror
. Якщо ви маєте попередження як попередження, ви зможете прийняти обгрунтоване рішення, чи все-таки має сенс запустити сесію налагодження, яку ви збиралися розпочати, або перервати її та спершу виправити попередження.
clippy
підшивальний інструмент для Іржі насправді попереджатиме про постійну "3,14". Це насправді приклад у документах . Але, як ви могли здогадатися з назви, clippy
пишається тим, що агресивно допомагає.
Оскільки хтось, хто працює зі застарілим вбудованим кодом C, включення попереджень компілятора допомогло показати багато слабких місць та областей для пошуку, коли пропонується виправлення. У ПКУ використання -Wall
і -Wextra
навіть -Wshadow
стали життєво важливими. Я не збираюся йти на кожну небезпеку, але перерахую кілька тих, що з’явилися, які допомогли показати проблеми з кодом.
Це може легко вказати на незавершену роботу та області, які можуть не використовувати всі передані змінні, які можуть бути проблемою. Давайте розглянемо просту функцію, яка може спровокувати це:
int foo(int a, int b)
{
int c = 0;
if (a > 0)
{
return a;
}
return 0;
}
Просто компілюючи це без -Wall або -Wextra не повертає жодних проблем. -Вілл скаже вам, хоча c
це ніколи не використовується:
foo.c: У функції 'foo':
foo.c: 9: 20: попередження: невикористана змінна 'c' [-Wunused-змінної]
-Wextra також скаже вам, що ваш параметр b нічого не робить:
foo.c: У функції 'foo':
foo.c: 9: 20: попередження: невикористана змінна 'c' [-Wunused-змінної]
foo.c: 7: 20: попередження: невикористаний параметр 'b' [-Wunused-parameter] int foo (int a, int b)
Цей трохи важкий і не з'являвся, поки не -Wshadow
був використаний. Давайте модифікуємо приклад вище, щоб просто додати, але просто трапляється глобальний з тим же ім'ям, що і локальний, що викликає багато плутанини при спробі використання обох.
int c = 7;
int foo(int a, int b)
{
int c = a + b;
return c;
}
Коли -Wshadow увімкнено, проблему легко помітити.
foo.c: 11: 9: попередження: оголошення "c" затінює глобальну декларацію [-Світ]
foo.c: 1: 5: Примітка: тіньова декларація тут
Для цього не потрібні додаткові прапорці в gcc, але це все ще є джерелом проблем у минулому. Проста функція, яка намагається надрукувати дані, але має помилку форматування, може виглядати так:
void foo(const char * str)
{
printf("str = %d\n", str);
}
Це не друкує рядок, оскільки прапор форматування неправильний, і gcc з радістю скаже вам, що це, мабуть, не те, що ви хотіли:
foo.c: У функції 'foo':
foo.c: 10: 12: попередження: формат '% d' очікує аргумент типу 'int', але аргумент 2 має тип 'const char *' [-Wformat =]
Це лише три з багатьох речей, які компілятор може перевірити для вас. Є багато інших, як використовувати неініціалізовану змінну, на яку вказували інші.
possible loss of precision
" та " comparison between signed and unsigned
". Мені важко зрозуміти, скільки «програмістів» ігнорує це (насправді я не дуже впевнений, чому вони не є помилками)
sizeof
не підписаний, а тип цілого числа за замовчуванням підписаний. Тип sizeof
результату size_t
, як правило, використовується для будь-якого, що стосується розміру типу, наприклад, наприклад, вирівнювання або кількість елементів масиву / контейнера, тоді як цілі числа загалом призначені для використання як ", int
якщо не потрібно іншого". Враховуючи, скільки людей при цьому навчають використовувати int
для перегляду своїх контейнерів (порівняння)int
з size_t
), помилка призведе до порушення всього. ; P
Це конкретна відповідь на C, і чому це набагато важливіше для C, ніж будь-що інше.
#include <stdio.h>
int main()
{
FILE *fp = "some string";
}
Цей код складається з попередженням . Що є і мають бути помилками майже в усіх інших мовах планети (мова забороненої збірки) - це попередження у C. Попередження на C майже завжди є помилками у маскуванні. Попередження слід фіксувати, а не придушувати.
З gcc
, ми робимо це якgcc -Wall -Werror
.
Це також стало причиною високої стійкості щодо деяких попереджуваних API попереджень щодо MS. Більшість людей, які програмують C, навчилися важкому способу трактувати попередження як помилки, і цей матеріал з'явився так, що просто не був таким самим видом і хотів виправити не портативний виправлення.
ПОПЕРЕДЖЕННЯ КОМПІЛЕРУ - ВАШ ДРУГА (не кричить, велика літера для наголосу).
Я працюю над застарілими системами Fortran-77. Компілятор повідомляє мені цінні речі: невідповідність типу аргументу під час виклику підпрограми, використовуючи локальну змінну до того, як значення буде встановлено у змінну, якщо у мене є аргумент змінної або підпрограми, який не використовується. Це майже завжди помилки.
Уникання тривалої публікації: Коли мій код складено чисто, 97% працює. Інший хлопець, з яким я працюю, компілює з усіма попередженнями, проводить години та дні у відладці, а потім просить мене допомогти. Я просто складаю його код із попередженнями і кажу йому, що виправити.
Ви завжди повинні включати попередження компілятора, оскільки компілятор часто може повідомити вам, що не так у вашому коді. Для цього ти проходиш-Wall -Wextra
до компілятора.
Зазвичай ви повинні трактувати попередження як помилки, оскільки попередження зазвичай означають, що з вашим кодом щось не так. Однак ігнорувати ці помилки часто дуже просто. Тому трактування їх як помилок призведе до виходу з ладу збірки, тому ви не зможете ігнорувати помилки. Щоб трактувати попередження як помилки, перейдіть -Werror
до компілятора.
Попередження компілятора в C ++ дуже корисні з деяких причин.
1 - Це дозволяє показати вам, де ви могли допустити помилку, яка може вплинути на кінцевий результат ваших операцій. Наприклад, якщо ви не ініціалізували змінну або якщо ви поставили "=" замість "==" (є лише приклади)
2 - Це дозволяє також показувати, де ваш код не відповідає стандарту c ++. Це корисно, тому що, якщо код відповідає фактичному стандарту, можна легко перенести код, наприклад, на іншу табличку.
Взагалі, попередження дуже корисні, щоб показати вам, де у вас є помилки у вашому коді, які можуть вплинути на результат вашого алгоритму або запобігти виникненню помилок, коли користувач буде використовувати вашу програму.
Ігнорування попереджень означає, що ви залишили неохайний код, який не тільки може спричинити проблеми в майбутньому для когось іншого, але й зробить важливі повідомлення про компіляцію менш поміченими вами. Чим більше вихід компілятора, тим менше хтось помітить або набридає. Чистіше, тим краще. Це також означає, що ви знаєте, що робите. Попередження дуже непрофесійні, необережні та ризиковані.
Я колись працював у великій компанії (Fortune 50), яка виготовляла електронне обладнання для тестування.
Основним продуктом моєї групи була програма MFC, яка протягом багатьох років приносила буквально сотні попереджень. Які були ігноровані майже у всіх випадках.
Це страшний кошмар, коли трапляються помилки.
Після цієї посади мені пощастило прийняти на роботу в якості першого розробника в новому стартапі.
Я заохочував політику "без попередження" для всіх збірок, при цьому рівень попередження компілятора встановлений досить шумно.
Наша практика полягала в тому, щоб використовувати #pragma попередження - push / ones / pop для коду, який розробник був впевнений, що це справді добре, а також протокол журналу на рівні налагодження, про всяк випадок.
Ця практика добре працювала у нас.
#pragma warning
не просто придушує попередження, він служить подвійним цілям швидкого повідомлення іншим програмістам про те, що щось є навмисним, а не випадковим, і виступає як тег пошуку для швидкого пошуку потенційно проблемних областей, коли щось ламається, але виправлення помилок / попереджень не робить полагодьте це.
Є лише одна проблема з поводженням з попередженнями як помилками: коли ви використовуєте код, що надходить з інших джерел (наприклад, бібліотеки мікро $ ** t, проекти з відкритим кодом), вони не виконали свою роботу правильно, а компілюючи їх код, створюється тон попереджень
Я завжди пишу свій код, щоб він не створював жодних попереджень або помилок, і очищаю його, поки він не компілюється, не створюючи сторонніх шумів. Сміття, з яким я маю працювати разом із мене, мене вражає, і я вражений, коли мені доводиться будувати великий проект і спостерігати за потоком попереджень, де компіляція повинна лише оголошувати, які файли обробляються.
Я також документую свій код, тому що я знаю, що реальна вартість програмного забезпечення в основному пов'язана з технічним обслуговуванням, а не з його написання спочатку, але це вже інша історія ...
-Wall
і ви використовуєте -Wall -Wextra
.
Деяке попередження може означати можливу смислову помилку в коді або можливий UB. Наприклад, ;
після if()
невикористаної змінної, глобальної змінної, замаскованої локальною, або порівняння підписаних і непідписаних. Багато попереджень пов'язані з аналізатором статичного коду в компіляторі або з порушеннями стандарту ISO, який можна виявити під час компіляції, які "потребують діагностики". Хоча ці випадки можуть бути законними в одному конкретному випадку, вони будуть наслідком проблем дизайну більшість часу.
Деякі компілятори, наприклад, gcc, мають варіант командного рядка для активації режиму "попередження як помилки", це приємний, якщо жорстокий інструмент для навчання початківців кодерів.
Той факт, що компілятори C ++ приймають компілюючий код, що, очевидно, призводить до невизначеної поведінки взагалі, є головним недоліком у компіляторах. Причина, чому вони цього не виправляють, полягає в тому, що це, мабуть, порушить деякі придатні складові.
Більшість попереджень повинні бути фатальними помилками, які не дають завершити збірку. За замовчуванням просто відображати помилки та робити так чи інакше збірку невірно, і якщо ви не перекриєте їх, трактуйте попередження як помилки та залиште деякі попередження, то, швидше за все, у вас закінчиться збій програми та виконання випадкових дій.
int i; if (fun1()) i=2; if (fun2()) i=3; char s="abcde"[i];
Цей код експонатів невизначений поведінка , якщо і тільки якщо обидва fun1()
і fun2()
може повернутися false
на те ж виконання функції. Що може бути, а може і не бути правдою, але як слід сказати компілятору?
Ви обов'язково повинні включити попередження компілятора, оскільки деякі компілятори погано повідомляють про деякі поширені помилки програмування, включаючи наступне: -
-> ініціалізація змінної забувається -> повертає значення функції пропускають -> прості аргументи в сімействах printf і scanf, що не відповідають рядку формату, використовується функцією, не заздалегідь оголошеною, хоча це відбувається лише в c
Оскільки ці функції можна виявити та повідомити, як правило, не за замовчуванням; тому цю функцію потрібно чітко запитувати через параметри компілятора.
Скористайтеся: вам не доведеться, не потрібно. -Wall та -Werror були розроблені самими маніаками, що рефакторингують код: його придумали розробники компілятора, щоб уникнути зламу існуючих збірок після оновлення компілятора на стороні користувача . Особливістю є нічого, але все стосується рішення розірвати чи не зламати збірку.
Цілком залежить від вашої переваги використовувати його чи ні. Я використовую його постійно, тому що це допомагає мені виправити свої помилки.
-Wall and -Werror was designed by code-refactoring maniacs for themselves.
[цитування потрібно]
-Wall
і -Werror
, це просто з проханням , якщо це гарна ідея. Що з вашого останнього речення звучить так, як ви говорите.