Это хорошая идея, чтобы устранить предупреждения компилятора? - PullRequest
16 голосов
/ 04 февраля 2009

В прошлом я работал с -Wall и другими ключами для gcc, чтобы исключить все предупреждения компилятора для проектов, в которых я принимал участие. Аналогично, на Perl я всегда программирую с использованием строгих правил и предупреждений об использовании (и часто - T), чтобы попытаться достичь наилучшего качества кода, которое я могу. Я понимаю, что несколько лет назад группа разработчиков Perl усердно работала над тем, чтобы заставить perl (интерпретатор Perl) корректно компилироваться в gcc со всеми включенными предупреждениями. Очевидно, они чувствовали, что это хорошая идея для качества кода. Я также понимаю, что в настоящее время программисты Perl добавляют еще больше предупреждений в свой код с помощью Perl :: Critic, который предупреждает их, когда они нарушают передовые методы, найденные в книге Perl Best Practices Дамиана Конвея (и из других источников, я полагаю).

У меня всегда было хорошее чувство в отношении кода, который я так очистил, но иногда я не мог избежать ощущения, что часть работы была немного потрачена впустую. Например, в моих вступительных классах C более десяти лет назад меня учили запускать функцию main () следующим образом:

void main(void) {

Это было минимально и могло использоваться только тогда, когда вы не возвращали значение и не обращались к вашим аргументам. В этом случае все работает отлично, но предупреждения gcc дадут вам понять, что эта функция должна выглядеть так:

int main(int args, char* argv) {

Должно быть, я набрал пару сотен неиспользованных int args, char * argv в тот день. Действительно ли я улучшил свой код или просто укоротил пальцы?

В настоящее время я программирую на Java в Eclipse, и наш проект содержит десятки тысяч предупреждений. Я бы хотел их почистить. Некоторые из них особенно трудно понять и устранить, но постепенно я учусь. Некоторые из них мне приходилось обрабатывать с помощью директив компилятора для подавления предупреждений (обычно крошечными минимальными методами, чтобы исключить плохую практику игнорирования предупреждений), но я также нахожу способы справиться с ними.

Стоит ли это времени программиста? Будет ли проект действительно лучше, если вы будете отслеживать каждое предупреждение компилятора?

Если ничего другого, похоже, было бы неплохо уменьшить количество предупреждений до нуля, чтобы серьезные предупреждения не потерялись в беспорядке.

Примечание : дубликат этого вопроса

Ответы [ 14 ]

28 голосов
/ 04 февраля 2009

Да, определенно. Предупреждение означает, что в вашем коде что-то не так. Либо вы исправляете это, либо вам следует отключить предупреждение - если вы не собираетесь на него реагировать, наличие предупреждения просто не дает вам определить, когда появляются новые предупреждения.

Самый простой способ получить и сохранить код без предупреждения - это просто всегда компилировать с -Werror (/ WX в Visual Studio) или эквивалентным ему.

8 голосов
/ 04 февраля 2009

Я согласен со всеми ответами, которые говорят «исправить их все», но я все же хотел бы представить противоположное мнение:

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

7 голосов
/ 04 февраля 2009

В C. есть два соответствующих прототипа main.

int main(void)

и

int main(int argc, char **argv)

void main(void) не является технически правильным, хотя он может поддерживаться некоторыми компиляторами как расширение стандарта.

Таким образом, в вашем конкретном случае вы можете использовать короткое объявление main, и, если оно будет соответствовать, оно не вызовет предупреждение.

7 голосов
/ 04 февраля 2009

Стоит ли это времени программиста? Будет ли проект действительно намного лучше, если вы будете отслеживать каждое предупреждение компилятора?

Да. Даже тривиальные сведения о несоответствии знаков могут оказать глубокое влияние на генерацию и оптимизацию кода.

5 голосов
/ 04 февраля 2009

Да. Даже тривиальные стоит исправить. Вот почему Некоторые из них, например пример main, который вы упомянули, возможно, не стоит исправлять самостоятельно, но они в совокупности. Большинство предупреждений компилятора избавят вас от прямой боли в долгосрочной перспективе. Они - ошибки, ожидающие, чтобы случиться (или даже случиться сейчас). Чтобы найти их, вам нужен простой способ их заметить. Если вы исправите все предупреждения, то каждое новое предупреждение помечается красным флагом и его легко заметить. Если вы исправите все критические проблемы, но оставите некоторые, как «основную» проблему, вы пропустите новые критические проблемы.

Что легче запомнить? Что любое предупреждение должно быть исправлено или что у вас вчера было 23 ненужных предупреждения в этой кодовой базе, и поэтому, если вы видите 24, вам нужно посмотреть?

В кодовой базе, над которой я работаю, мы говорим компилятору генерировать ошибки во всех предупреждениях. Это заставляет нас их исправлять и сохраняет код в лучшей форме. Если есть предупреждение, которое действительно не стоит исправлять, всегда есть #pragma, чтобы оно исчезло. Таким образом, у вас все еще есть яркая линия для неудачи.

4 голосов
/ 04 февраля 2009

Я собираюсь пойти против пакета и сказать, что могут быть некоторые предупреждения компилятора, которые не стоит исправлять. Пример следует:

У нас есть много кода, который был написан до Java 1.5 и дженерики. Это все еще работает. Eclipse также генерирует буквально тысячи предупреждений о непараметризованных коллекциях. Практически все эти коллекции ограничены в объеме; они никогда не сломаются. Но подождите, вы можете спросить; как насчет нескольких коллекций, которые не ограничены в объеме? Разве вы не рискуете где-нибудь коллекцией, содержащей экземпляр чего-то, что никогда не должно там появляться?

Ответ: большая часть этого кода также не изменилась. Это наследие; новый код не изменяет эти коллекции, и этот код использовался годами без проблем. Он все еще находится в нашей кодовой базе, и мы должны его поддерживать, если обнаружится ошибка, но на практике это сделано. Трата времени, необходимого для параметризации всех этих общих коллекций, отнимает время у других необходимых проектов.

Обратите внимание на предостережения здесь:

  • Код использовался долгое время время без сообщений об ошибках.
  • Код не подвергается существенному редактированию.

Если что-то из этого перестает быть правдой - скажем, например, ошибка внезапно проявляется , и мы должны войти и отредактировать - предупреждения внезапно становятся более целесообразными для исправления. (Между прочим, на этом этапе их тоже очень недорого исправить; мы можем исправлять соответствующие блоки по мере исправления ошибки.)

3 голосов
/ 04 февраля 2009

Да, сделайте это ..

Буквально вчера я сделал это для проекта на работе. При удалении предупреждений я обнаружил две проблемы, которые оказались реальными ошибками.

Это был C-проект, и в одном источнике был назван sqrt (квадратный корень). Я получил следующее предупреждение:

test.c:4: warning: implicit declaration of function 'sqrt'

Оказалось, что кодер забыл включить правильный заголовочный файл и квадратный корень вызывался с целочисленными аргументами, а не с плавающей точкой. Это было явно неправильно, а не то, что он намеревался.

Предупреждение было там довольно давно, но никто не видел его, потому что оно было потеряно в других 1000 безобидных предупреждениях, которые просто прокручивались по экрану. Предупреждения существуют по причине.

Кстати, исправление предупреждений заняло у меня около 4 часов ... Это ничто по сравнению со временем, которое потребовалось для написания всего этого.

2 голосов
/ 05 февраля 2009

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

Однако, если они делают это и видят множество предупреждений, это предупреждения, которые всегда существовали, или они неправильно установили компилятор на свой ПК?

По крайней мере, если есть правило (и поле для отметки в контрольном списке, если вы его используете), что код должен компилироваться без предупреждений, тогда вы избежите этой двусмысленности.

(* Кто-то еще может включать ваше будущее я).

2 голосов
/ 04 февраля 2009

Чтобы добавить предупреждения, вот что разработчик гномов использует в своем коде:

http://blogs.gnome.org/otte/2008/12/22/warning-options/

2 голосов
/ 04 февраля 2009

Eclipse, IntelliJ и другие современные системы обеспечения качества кода имеют огромное количество доступных предупреждений.

Очистка предупреждений является полезной практикой, если только по какой-либо другой причине, кроме как для уменьшения шума. Ваш код, вероятно, уже содержит некоторые из них, которые являются реальными ошибками.

Однако многие из предупреждений, вероятно, являются поддельными. Некоторые предупреждения от Eclipse - это такие вещи, как микрооптимизация или стилистический придирки. Это означает, что некоторые из ваших очисток должны изменять настройки вашего инструмента, а не изменения кода или локализованные директивы подавления.

...