Хорошие подходы для обеспечения построения с повышенным уровнем предупреждения для нового кода C++

Я унаследовал большую кодовую базу C++ для нескольких приложений Windows, которая успешно используется многими клиентами.

  • Кодовая база большая, >1 мельница LOC.
  • Кодовая база имеет историю более 15 лет.
  • В некоторых областях кодовая база доминирует в стиле программирования C и / или не очень современном стиле C++, например, не используя стандартные коллекции и алгоритмы C++.
  • К сожалению, кодовая база была скомпилирована только с уровнем предупреждения 2 (/W2 в Visual C++). Я хотел бы перейти на уровень 3 (/W3), чтобы повысить безопасность и подготовиться к 64-битной.

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

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

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

6 ответов

Решение

Я бы даже пошел до уровня предупреждения 4 (/W4).


Поскольку вы используете Visual Studio, довольно просто подавить надоедливые предупреждения, такие как сравнение со знаком и без знака:

#pragma warning(disable:NNNN)

куда NNNN это номер вашего предупреждения. Теперь поместите все эти отключенные предупреждения в файл заголовка (скажем, "tedious_warnings.h") и принудительно включите этот файл заголовка везде - Свойства проекта -> C/C++ -> Дополнительно -> Файл принудительного включения.
Позже или, что лучше, как можно скорее, удалите принудительное включение и пройдите через предупреждения, поскольку большинство из них довольно легко исправить (size_t вместо этого, если int, так далее).

Возможно, вы могли бы создать новый код в отдельных DLL или библиотеках. Таким образом, вы можете применить свой более высокий уровень предупреждений (и я бы сказал, перейдите к /W4 и будьте готовы отключить несколько предупреждений MS dfter, а не соглашаться на /W3) без необходимости просматривать тысячи предупреждений из старого кода.

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

Вам может не понравиться ответ...

удалите предупреждения, исправив ошибки.

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

вам нужно уменьшить шум предупреждений, чтобы люди могли видеть добавляемые предупреждения (на желаемом уровне предупреждения).

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

если вы не знаете, действительны ли преобразования / сравнения, вы всегда можете использовать шаблонную функцию с действием ошибки (assert, throw, log) для выполнения логики в случае сомнений.

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

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

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

Я бы использовал инкрементальный подход.

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

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

Это означает, что любой измененный файл должен быть без предупреждения.

Однако, будем откровенны, разработчики всегда находят способы игры в систему.

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

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

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

Другие вопросы по тегам