Это хорошая идея для устранения предупреждений компилятора?
В прошлом я работал с -Wall и другими переключателями для gcc, чтобы исключить все предупреждения компилятора для проектов, в которых я был вовлечен. Аналогично, в Perl я всегда программирую с использованием строгих и предупреждающих предупреждений (а часто - T), чтобы попытаться достичь лучшего качества кода, которое я могу. Я понимаю, что несколько лет назад группа носителей Perl много работала, чтобы сделать perl (интерпретатор Perl) компилироваться под gcc с включенными предупреждениями. Очевидно, они считали, что это хорошая идея для качества кода. Я также понимаю, что в наши дни программисты Perl добавили еще больше предупреждений в свой код с Perl:: Critic, который предупреждает их, когда они нарушают лучшие практики, найденные в книге Damian Conway Perl Best Practices (и из других источников, я считаю).
У меня всегда было хорошее представление о коде, который я очистил таким образом, но иногда я не мог избежать чувства, что часть работы была немного потрачена впустую. Например, в моих вводных классах C более десяти лет назад меня научили запускать мою функцию main() следующим образом:
void main(void) {
Это было минимально и могло использоваться только тогда, когда вы не возвращали значение и не обращались к своим аргументам. Он отлично работает в этом случае, но предупреждения gcc дадут вам знать, что эта функция действительно должна выглядеть так:
int main(int args, char* argv) {
Я, должно быть, набрал пару сотен неиспользуемых int args, char * argv строк в тот же день. Я действительно улучшил свой код или просто опустил пальцы вниз?
В настоящее время я программирую на Java в Eclipse, и наш проект содержит десятки тысяч предупреждений. Я бы хотел их очистить. Некоторые из них особенно трудно понять и устранить, но я медленно учусь. Некоторым из них я должен был обращаться с директивами компилятора, чтобы подавлять предупреждения (как правило, в минимальных минимальных методах, чтобы исключить плохую практику игнорирования предупреждений), но я также нашел способы справиться с ними.
Стоит ли это время программиста? Будет ли проект действительно намного лучше, если вы выберете каждое предупреждение о компиляторе?
Если ничего другого, похоже, было бы неплохо уменьшить количество предупреждений до нуля, чтобы серьезные предупреждения не потерялись в беспорядке.
Примечание: Дубликат этого вопроса
Ответы
Ответ 1
Да, определенно. Предупреждение указывает на то, что в вашем коде может быть что-то неправильное. Либо вы его исправляете, либо вы должны отключить предупреждение - если вы не собираетесь действовать на нем, предупреждение просто мешает вам обнаруживать, когда появляются новые предупреждения.
Самый простой способ получить и оставить код без предупреждения - просто всегда компилировать с помощью -Werror (/WX в Visual Studio) или эквивалентно.
Ответ 2
Я согласен со всеми ответами, которые говорят "исправить их все", но я все же хотел бы представить противоположный взгляд:
Существуют устаревшие системы, в которых некоторые (многие или все) компоненты не имеют специального сопровождения, а большие части системы в основном неизвестны. Устранение предупреждений компилятора в таком неизвестном коде может занять значительное количество кода (поскольку для каждого предупреждения необходимо понимать код вместе со своим контекстом) и вводит возможный источник ошибок (некоторый код зависит от поведения undefined). И поскольку такие устаревшие системы редко имеют обширное покрытие для тестирования, вы даже не можете полагаться на тесты, чтобы уведомлять вас о регрессиях.
Ответ 3
Стоит ли это время программиста? Будет ли проект действительно намного лучше, если вы выберете каждое предупреждение о компиляторе?
Да. Даже тривиальные о несоответствии знака могут оказать глубокое влияние на формирование и оптимизацию кода.
Ответ 4
Существует два совместимых прототипа для main в C.
int main(void)
и
int main(int argc, char **argv)
void main(void)
не является технически корректным, хотя некоторые компиляторы могут поддерживаться как расширение стандарта.
Итак, в вашем конкретном случае вы можете использовать краткое объявление main
и, если оно соответствует требованиям, оно не будет вызывать предупреждение.
Ответ 5
Да. Даже тривиальные ценности заслуживают внимания. Вот почему. Некоторые, как пример основной, о которой вы упоминаете, вероятно, не заслуживают самостоятельной фиксации, но они в совокупности. Большинство предупреждений компилятора избавят вас от прямой боли в долгосрочной перспективе. Они - жуки, ожидающие, что они произойдут (или даже случаются сейчас). Чтобы найти их, вам нужен простой способ их заметить. Если вы исправите все предупреждения, каждое новое предупреждение будет красным флагом и его легко заметить. Если вы исправите все критические, но оставите что-то вроде "основной" проблемы, вы пропустите новые критические.
Что легче запомнить? Чтобы любое предупреждение было исправлено или что у вас было 23 неулокальных предупреждения в этой базе кода вчера, поэтому, если вы видите 24, вам нужно взглянуть?
В базе кода, над которой я работаю, мы сообщаем компилятору генерировать ошибки во всех предупреждениях. Это заставляет нас исправить их и сохранить код в гораздо лучшей форме. Если есть предупреждение, которое действительно не стоит исправлять, всегда есть #pragma, чтобы он исчез. Таким образом, у вас все еще есть яркая линия для отказа.
Ответ 6
Я собираюсь двигаться против пакета здесь и сказать, что могут быть некоторые предупреждения компилятора, которые не стоит исправлять. Пример:
У нас есть много кода, который был написан до Java 1.5 и generics. Он по-прежнему работает. Eclipse также генерирует буквально тысячи предупреждений о непараметризированных коллекциях. Практически все эти коллекции ограничены по охвату; они никогда не сломаются. Но подождите, вы можете спросить; как насчет нескольких коллекций, которые не ограничены по охвату? Разве вы не рискуете коллекцией где-нибудь, где есть экземпляр чего-то, что никогда не должно туда заходить?
Ответ: много этого кода также не изменилось. Это наследие; новый код не модифицирует эти коллекции, и этот код использовался годами без проблем. Это все еще в нашей кодовой базе, и мы должны были бы поддерживать ее, если бы обнаружилась ошибка, но на практике она выполняла свою работу. Проводя время, необходимое для параметризации всех этих общих коллекций, потребуется время от других необходимых проектов.
Обратите внимание на следующие оговорки:
- Код использовался для долгого
время без сообщений об ошибках.
- Код не подвергается существенному редактированию.
Если любое из этих остановок будет истинным - скажем, например, ошибка внезапно проявляется, и нам нужно войти и отредактировать - предупреждения внезапно становятся более целесообразными для исправления. (Кстати, они очень недорогие, чтобы исправить в этот момент, также, мы можем исправить соответствующие блоки по мере исправления ошибки.)
Ответ 7
Да, сделайте это.
Вчера я сделал это для проекта на работе. При удалении предупреждений я обнаружил две проблемы, которые оказались настоящими ошибками.
Это был C-проект, и в одном из них был вызван sqrt (квадратный корень). Я получил следующее предупреждение:
test.c:4: warning: implicit declaration of function 'sqrt'
Оказалось, что кодер забыл включить правильный заголовочный файл, а квадратный корень вызывается с целыми аргументами, а не с плавающей точкой. Это было явно неправильно, а не то, что он намеревался.
Предупреждение было довольно долго, но никто не видел его, потому что он потерялся в других 1000 безобидных предупреждениях, которые просто прокручивались по экрану. Предупреждения существуют по какой-то причине.
Btw - исправление предупреждений заняло меня, как... 4 часа... Это ничего по сравнению с временем, которое потребовалось, чтобы написать все это.
Ответ 8
Eclipse, IntelliJ и другие современные системы качества кода имеют огромное количество доступных предупреждений.
Очистка предупреждений - полезная практика, если не для того, чтобы успокоить шум. Возможно, у вашего кода уже есть некоторые из них, которые являются настоящими ошибками.
Однако многие из предупреждений, вероятно, являются фиктивными. Некоторые предупреждения от Eclipse - это такие вещи, как микро-оптимизация или стилистика. Это означает, что некоторые из ваших исправлений должны настраивать настройки вашего инструмента, а не изменения кода или локализованные директивы подавления.
Ответ 9
Просто добавьте предупреждения, вот что разработчик gnome использует в своем коде:
http://blogs.gnome.org/otte/2008/12/22/warning-options/
Ответ 10
Еще одна причина гарантировать, что ваш код компилируется без предупреждений, заключается в том, что если кто-то еще * должен внести изменения в код в какой-то момент в будущем, хорошее место для начала - убедиться, что они могут скомпилировать код в его текущей форме.
Однако, если они это делают и видят множество предупреждений, являются ли эти предупреждения, которые всегда существовали, или они неправильно установили компилятор на своем ПК?
По крайней мере, если есть правило (и поле для отметки в контрольном списке, если вы используете его), что код должен компилироваться без предупреждений, тогда вы избегаете этой двусмысленности.
(* Кто-то может включать ваше будущее).
Ответ 11
Он сохранит компилятор времени написания предупреждений и упростит поиск потенциально опасных предупреждений, если вы уменьшите количество легкомысленных предупреждений в коде.
Стоит ли это того, что нужно, чтобы выследить все предупреждения и исправить? Обычно это не... но стоит ли устанавливать предупреждения, когда они очевидны и легко исправляются, или когда вам нужно потратить время и изменить логику, содержащую предупреждения, по другой причине.
Ответ 12
Мое мнение. Да.
Как вы сказали в конце. Это помогает сделать реальные ошибки более заметными.
При запуске Perl cgi script, который выводит предупреждения на сервере Apache, предупреждения регистрируются в error.log. Зачем тратить пространство. Исправьте предупреждения.
Также я думаю, что это опыт обучения, чтобы лучше понять язык и компилятор. Я не понимал, что динамическое масштабирование - это даже особенность Perl, пока я не начал использовать строгий.
Ответ 13
Ваш пример - прекрасная иллюстрация, почему предупреждения не следует игнорировать. void main(void)
является недопустимым прототипом (но int main(void)
работает!)), и ваш код может сломаться на некоторых компиляторах. Ваш компилятор был достаточно хорош, чтобы указать на это.
Я обнаружил, что почти каждое предупреждение фактически указывало на настоящую проблему, даже если я не смог понять причину в то время. В принципе, я всегда что-то делал и думал о другом. Эффект, возможно, был достигнут в любом случае, но только по чистому совпадению.
Рассматривайте предупреждения как ошибки. Исключения существуют (есть один в компиляторе VB.NET относительно неинициализированных типов значений), но они чрезвычайно редки. И если вы когда-нибудь наткнетесь на одно из этих исключений, вы это узнаете.
Ответ 14
Вы всегда должны стараться, чтобы при компиляции не возникало никаких предупреждений. Таким образом, новые предупреждения привлекают внимание. (Мой самый неприятный опыт в этом был компилятором AIX С++ еще в 2002 году, который выплеснул сотни предупреждений для кода, который даже не был сильно замаскирован.)
Знайте, что означает каждое предупреждение. В вашем случае вы должны ввести стандартный int main()
, а не неправильный void main(void)
или неуклюжий int main(int argc, char **argv)
. Устраните, что вы можете, и подавите предупреждения, которые вы сочтете приемлемыми.
Возможно, вы не захотите исправлять каждое предупреждение. Как говорит Saua, существуют устаревшие системы, в которых предупреждения о блокировке абсолютно опасны, и сложные системы, такие как CGAL, где вы также не хотите гадать код. При конвертировании наших приложений на запуск до 64 бит я обнаружил случаи, когда я мог исключить предупреждение только с помощью броска, что потенциально могло бы вызвать другие проблемы. Мы подавили это предупреждение.