Почему бы точно не рассматривать все предупреждения как ошибки, если в стороннем коде нет предупреждений? - PullRequest
3 голосов
/ 08 ноября 2011

Этот вопрос не является специфическим для C ++, он просто использует C ++ в качестве примеров.

Широко распространено мнение, что "обрабатывать все предупреждения как ошибки" (например, /WX опция Visual C ++) хорошо, потому что предупреждение - это ошибка, ожидающая появления (кстати, связанный поток полон операторов "Я нацеливаюсь на нулевые предупреждения").

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

Хорошо, давайте на время этого вопроса представим, что у компилятора есть средства для временного отключения предупреждений в некотором коде (например, в Visual C ++):

#pragma warning(push)
#pragma warning(disable:X)
#include <ThirdParty.h>
#pragma warning(pop)

, а затем сторонний код больше не проблема.

Предполагая, что мы полностью контролируем весь код (без сторонних или мы можем отключить предупреждения только в стороннем коде), каковы причины того, чтобы не рассматривать предупреждения как ошибки?

Ответы [ 5 ]

6 голосов
/ 08 ноября 2011

Потому что иногда вы знаете лучше, чем компилятор.

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

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

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

Другой вероятный случай - использование нестандартной функции, которую дает компилятор.предупреждение о.Например, в MSVC10 это:

enum TypedEnum : int32_t
{
    ... 
};

выдаст предупреждение о нестандартном расширении.Полностью действительный код, когда вы пишете код для своего компилятора, но все равно выдает предупреждение (я полагаю, на уровне 4)Многие функции теперь в C ++ 11, которые ранее были реализованы как специфичные для компилятора функции, будут следовать за этим (полностью безопасно, полностью допустимо, все еще предупреждение).

Другой безопасный случай, который выдает предупреждение, - форсированиезначение в bool, например:

bool FlagSet(FlagType flags) { return (flags & desired); }

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

Теперь, этот пример схематичен, так как вы можете легко закодировать его, но это поднимает другой вопрос: могут быть моменты, когда есть два разных способа сделать что-то, что дает одинаковые результаты, скорость и надежность,но одно менее читаемо, а другое менее правильно.Вы можете выбрать код уборщика вместо правильного кода и вызвать предупреждение.

В других случаях возможна потенциальная проблема, к которой относится предупреждение.Например, в описании MSVC C4683 буквально говорится: «будь осторожен, когда ...» Это предупреждение в классическом смысле этого слова: может произойти что-то плохое.Если вы знаете, что делаете, это не применимо.

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

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

4 голосов
/ 17 июля 2015

Я не согласен с утверждениями "вообще нет причин".

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

Я использовал оба подхода в командах: 1) предупреждения как ошибки и 2) нулевые предупреждения как политика, но не соблюдаются компилятором.В обоих случаях выпуски были сделаны без предупреждений, а уровни предупреждений оставались около нуля.В последнем случае, однако, иногда возникали состояния, когда уровень предупреждений в течение короткого периода времени достигал нескольких единиц.

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

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

В конце концовподписанный материал исчезнет, ​​но в данный момент вы получаете предупреждение о том, что сравниваются подписанные и неподписанные целые числа.Если ваша компания применяет бесплатные сборки предупреждений, вы можете:

  1. Для статического вещания.
  2. Ввести некоторый ненужный временный код.
  3. Идти на большой скорости - переносить всевещь сразу.

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

В этот момент некоторые люди будут утверждать: «Да, но люди не будут достаточно мотивированы"или" не моя команда, они все дерьмо ", или так далее (по крайней мере, я часто слышал эти аргументы).Я нахожу, что это, как правило, Фундаментальная ошибка атрибуции .Если вы относитесь к своим коллегам так, как будто они безответственные, безразличные, они будут склонны вести себя таким образом.

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

Команда 1: предупреждения как предупреждения, но не допускаются

В команде 1 мы отслеживали количество предупреждений у Дженкинса, а на наших слабых совещаниях команды мы говорили о количестве предупреждений.Это была команда из 5 человек, о которой двое из нас действительно заботились.Когда один из нас снизит уровень предупреждения, другой будет петь на собрании.При очистке предупреждения удалили неизвестную ошибку, мы рекламировали этот факт.Через несколько месяцев к этому времени присоединились 2 из 5 других кодировщиков, и мы быстро (в течение года) сократили количество предупреждений до нуля.Время от времени предупреждения накапливались, иногда в десятках или двадцатых.Когда это произошло, зашел ответственный разработчик, извинился и объяснил, почему они были там и когда они ожидали его почистить.Тот парень, который никогда не был мотивирован, по крайней мере был достаточно мотивирован давлением со стороны сверстников не добавлять никаких предупреждений.

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

Команда2: Предупреждения как ошибки

Команда 2 была практически идентична команде 1 в начале.Такой же большой унаследованный код, полный предупреждений.Одинаковое количество разработчиков, мотивированных и немотивированных.В команде 2, хотя один из нас (я) хотел оставить предупреждения как предупреждение, но сосредоточиться на уменьшении предупреждений.Мой другой целеустремленный коллега утверждал, что все остальные разработчики были ** дырами, и если мы не допустим ошибок предупреждений, они никогда не избавятся от них, и какую возможную выгоду вы можете получить от этого?Я объяснил свой опыт в команде 1, но у него ничего не было.

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

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

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

Другой пример, который привеля обнаружил этот вопрос и написал этот ответ, это [[не рекомендуется]] функция C ++ 11, которую я хотел бы использовать для пометки устаревшего кода, чтобы мы могли постепенно исключить его как часть нашей очистки предупреждений.Это, однако, несовместимо с «все предупреждения как ошибки».

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

4 голосов
/ 08 ноября 2011

Я видел 3 причины:

  • устаревший код: это огромная задача - взять код, который пронизан предупреждением, и медленно обновить его, чтобы он соответствовал.Как и любая модификация, существует риск появления новых ошибок.Иногда потенциальная выгода не стоит риска.
  • невежество: чаще всего это не осознанное решение, многие люди не играют с настройками компилятора
  • лень: aka,подметать под ковер, надеюсь, только для хобби-проектов (я оптимист, я оптимист, я оптимист ...)

Устаревший код, конечно, вызывает беспокойство, но его можно решитьс помощью:

  • трактовать устаревший код как сторонний код (он же Великая китайская стена)
  • реформировать код, по одному файлу за раз (используя «UglyWarningDeactivator.h» для нереформированных) или по одному предупреждению за один раз (путем выборочного их включения)

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


На новой базе кода?Нет причин вообще.В худшем случае, если вам действительно нужно что-то хитрое (введите puning, ...), вы всегда можете выборочно деактивировать предупреждение для соответствующей области кода.И что действительно здорово, так это то, что он документирует, что происходит что-то подозрительное!

2 голосов
/ 08 ноября 2011

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

Кроме того, наличие трех категорий Fatal / Warning / Benign позволяет много возможностей для добавления крошечных кусочковполезная информация для категории Предупреждение (см. C4061 ) без нарушения сборки.С одним лишь фатальным или нет различием список предупреждений должен был бы быть более разумным.

1 голос
/ 31 мая 2014

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...