Анализ качества кода С++ приложений для Магазина Windows с помощью функций анализа кода Visual Studio
Средство анализа кода в Microsoft Visual Studio Express 2012 для Windows 8 анализирует код на предмет распространенных проблем и нарушений хорошего стиля программирования. Предупреждения, возникающие в ходе анализа кода, отличаются от ошибок и предупреждений компилятора, потому при анализе кода выполняется поиск конкретных шаблонов кода, которые являются допустимыми, но тем не менее могут вызвать проблемы при использовании кода вами или другими специалистами. Анализ кода позволяет находить дефекты в коде, которые невозможно обнаружить в процессе тестирования. Регулярный запуск средства анализа кода в процессе разработки позволяет создать приложение более высокого качества.
Примечание
В Visual Studio Ultimate 2012, Visual Studio Premium 2012 и Visual Studio Professional 2012 можно пользоваться всеми функциональными возможностями анализа кода. См. статью Анализ качества приложений с помощью средств анализа кода в библиотеке MSDN.
Содержание раздела
Рассматриваются следующие вопросы:
Анализ и разрешение предупреждений анализа кода
Подавление предупреждений анализа кода
Поиск и фильтрация результатов анализа кода
Предупреждения анализа кода C++
Запуск анализа кода
Чтобы запустить анализ кода для решения Visual Studio, выполните следующие действия:
- В меню Построение выберите Выполнить анализ кода в решении.
Чтобы анализ кода автоматически запускался при каждом построении проекта, выполните следующие действия:
Выберите имя проекта в обозревателе решений и затем выберите Свойства.
На странице свойств проекта выберите Анализ кода и установите флажок Включить анализ кода для C/C++ при построении.
Решение компилируется, и запускается анализ кода. Результаты выводятся в окне "Анализ кода".
Анализ и разрешение предупреждений анализа кода
Чтобы проанализировать конкретное предупреждение, выберите заголовок предупреждения в окне "Анализ кода". Предупреждение разворачивается, позволяя просмотреть подробные сведения о проблеме. Когда возможно, в анализе кода отображаются номер строки и логика анализа, которые стали причиной предупреждения.
При разворачивании предупреждения строки кода, которые вызвали предупреждение, выделяются в редакторе кода Visual Studio.
Поняв, в чем заключается проблема, можно разрешить ее в коде. После этого необходимо снова запустить анализ кода, чтобы убедиться, что предупреждение больше не отображается в окне "Анализ кода", и что исправление не привело к появлению новых предупреждений.
Совет
Повторно запустить анализ кода можно из окна "Анализ кода". Нажмите кнопку Анализировать и выберите область анализа. Можно повторно запустить анализ для всего решения или для выбранного проекта.
Подавление предупреждений анализа кода
В некоторых случаях разработчик может принять решение не разрешать предупреждение анализа кода. Возможно, разрешение предупреждения требует слишком значительного переписывания кода в сравнении с вероятностью того, что проблема проявит себя в какой-либо реальной его реализации. Или, например, разработчик может посчитать, что используемая в предупреждении логика анализа не соответствует данному контексту. Можно подавить отдельные предупреждения, чтобы они больше не отображались в окне "Анализа кода".
Чтобы подавить предупреждение, выполните следующие действия.
Если подробные сведения не отображаются, разверните заголовок предупреждения.
Выберите ссылку Действия внизу предупреждения.
Выберите Подавить сообщение и затем выберите В исходном.
При подавлении сообщения вставляется конструкция #pragma(warning:идентификатор_предупреждения), которая отключает предупреждение для строки кода.
Поиск и фильтрация результатов анализа кода
Можно выполнять поиск в длинных списках предупреждений, а также фильтровать предупреждения в решениях, состоящих из нескольких проектов.
Предупреждения анализа кода C++
Для кода C++ анализ кода вызывает следующие предупреждения:
Правило |
Описание |
---|---|
Использование неинициализированной памяти |
|
Разыменование пустого (NULL) указателя |
|
Использование значения unchecked |
|
Вызов завершается нулем |
|
Неверное объединение |
|
Пропущен строковый аргумент функции форматирования |
|
Пропущен целочисленный аргумент функции форматирования |
|
Пропущен аргумент-указатель функции форматирования |
|
Пропущен аргумент указателя на строку для функции форматирования |
|
Возврат неинициализированной памяти |
|
Индекс превышает максимальный размер буфера |
|
Индекс превышает максимальный размер буфера стека |
|
Пропущен аргумент с плавающей запятой для функции форматирования |
|
Лишний аргумент у функции форматирования |
|
Аргумент не с плавающей запятой у функции форматирования |
|
Нецелочисленный аргумент у функции форматирования |
|
Несимвольный аргумент у функции форматирования |
|
Недопустимое приведение строки |
|
Недопустимый вызов CreateProcess |
|
Недопустимый объект в качестве аргумента функции форматирования |
|
Приоритет логического НЕ и побитового И |
|
Приоритет логического НЕ и побитового ИЛИ |
|
Недопустимый аргумент в виде строки символов у функции форматирования |
|
Недопустимый аргумент в виде строки расширенных символов у функции форматирования |
|
Несоответствие размера и количества |
|
Недопустимый переменный аргумент при вызове функции |
|
Возможное несоответствие типа аргумента |
|
Переполнение при чтении |
|
Переполнение при записи |
|
Недопустимое значение параметра |
|
Недопустимое свойство атрибута |
|
Конфликт значений свойств атрибутов |
|
Ссылки не могут быть пустыми (NULL) |
|
Значение NULL у переменной, не являющейся указателем |
|
MustCheck для Void |
|
Размер буфера для массива или переменной, не являющейся указателем |
|
Несоответствие свойства Null при Deref=0 |
|
Попытка записи константы |
|
Использование return в предусловии |
|
Завершение нулем у переменной, не являющейся указателем |
|
Свойство MustCheck должно иметь значение Yes или No |
|
Размер элемента без размера буфера |
|
Размер буфера превышает размер массива |
|
Размер буфера для переменной, не являющейся указателем |
|
Нет свойств у атрибута |
|
Допустимый размер у буфера, недоступного для чтения |
|
Записываемый размер у буфера, недоступного для записи |
|
Недопустимая аннотация: значение свойства NeedsRelease должно быть равно Yes или No |
|
Разыменование строки недопустимого размера |
|
Недопустимый размер у строкового типа |
|
Недопустимый размер строкового параметра |
|
Недоступное расположение у строки недопустимого размера |
|
Недопустимый размер у типа строкового буфера |
|
Недопустимая аннотация: свойство NeedsRelease не может использоваться для значений типа void |
|
Неизвестный стиль строки формата |
|
Если для данной функции использовать аннотации атрибута, все ее существующие аннотации __declspec станут недействительными |
|
Недопустимая спецификация размера: синтаксический анализ выражения невозможен |
|
Недопустимый Deref= или Notref=: синтаксический анализ выражения невозможен |
|
Значение не является одним из допустимых значений (Yes/No/Maybe) |
|
Значение не является строковым |
|
Значение не является числом |
|
Непредвиденная ошибка выражения аннотации |
|
Ожидаемое число аргументов для аннотации не соответствует фактическому числу аргументов для аннотации |
|
Непредвиденная ошибка аннотации |
|
Аннотируемый параметр должен быть указателем |
|
Разыменование пустого (NULL) указателя. Указатель содержит то же значение NULL, которое находилось в другом указателе |
|
Недопустимая ссылка на нестатический член |
|
Неоднозначная ссылка на член класса |
|
_Success_ или _On_failure_ используется в недопустимом контексте |
|
Левый операнд указывает на структуру, используйте "->" |
|
Левый операнд является структурой, используйте "." |
|
Аннотации для контекста __on_failure не должны находиться в явном предварительном контексте |
|
Для SAL_context ожидалось имя статического контекста |
|
Для аннотации ожидалось выражение указателя |
|
Аннотация _Use_decl_annotations_ должна использоваться для ссылки, без изменения, перед объявлением |
|
Допустимые имена параметров атрибута: p1...p9 |
|
typefix нельзя применять к параметру, который уже имеет typefix |
|
Аннотация checkReturn применяется только к постусловиям для конкретного параметра функции |
|
Для функции число параметров аннотации не совпадает с числом параметров, обнаруженных в файле |
|
Для параметра функции принадлежащий аннотации параметр не совпадает с параметром, найденным в файле |
|
Для параметра аннотации ожидался член перечисления |
|
Для параметра аннотации ожидалось целочисленное выражение |
|
Для параметра аннотации ожидалось строковое выражение |
|
Для аннотации ожидалось __yes, __no или __maybe |
|
В аннотации не найден ожидаемый токен или идентификатор |
|
Аннотации требуются параметры |
|
Неправильное число обязательных параметров в аннотации |
|
Аннотация не может также быть PrimOp (в текущем объявлении) |
|
Аннотация не может также быть PrimOp (см. предыдущее объявление) |
|
Параметр аннотации: невозможно использовать тип в аннотации |
|
Аннотация не поддерживает параметры |
|
Тип параметра не содержит членов |
|
Аннотация допустима только для массива |
|
Ни к одной аннотации не применено pre, post или deref |
|
pre, post или deref применено к блоку |
|
Выражение __at не применяется к текущей функции |
|
Функция не может использоваться изолированно как аннотация |
|
Аннотацию нельзя использовать в выражениях |
|
Аннотация в параметре больше не поддерживается |
|
Аннотация в параметре содержит несколько значений value, stringValue и longValue. Используйте paramn=xxx |
|
Аннотация в параметре одновременно содержит значение value, stringValue или longValue и выражение paramn=xxx. Используйте только paramn=xxx |
|
Аннотация в параметре содержит param2, но не содержит param1 |
|
Аннотация для функции в параметре не распознана |
|
Аннотации для функции в параметре требуется больше разыменований, чем допускает фактический аннотируемый тип |
|
Аннотация для функции аннотирует "this" в функции, не являющейся членом |
|
Аннотация в параметре для функции не соответствует типу параметра |
|
Несогласованная аннотация функции: предыдущий экземпляр содержит ошибку |
|
Несогласованная аннотация функции: этот экземпляр содержит ошибку |
|
Несогласованная аннотация функции: параметр имеет другие аннотации в этом экземпляре |
|
Несогласованная аннотация функции: параметр имеет другие аннотации в этом экземпляре |
|
Dynamic_cast<>() не поддерживается в аннотациях |
|
В функции обнаружена синтаксическая ошибка аннотации |
|
Во встроенной аннотации обнаружена синтаксическая ошибка условной аннотации |
|
Значения списков результатов должны быть константами |
|
В аннотациях для функции обнаружена синтаксическая ошибка для аннотации |
|
Аннотация для функции: параметр не согласуется с объявлением функции при проверке |
|
Подсказки для функции не согласуются с объявлением функции |
|
Значение параметра для _Macro_value_ равно NULL |
|
Для символа обнаружен begin без соответствующего end |
|
Для символа обнаружен end без соответствующего begin |
|
Строки формата должны находиться в предусловиях |
|
Для функции: синтаксическая ошибка в параметре |
|
Для функции: синтаксическая ошибка рядом с окончанием |
|
Для функции: синтаксическая ошибка в аннотации _At_() (не распознано имя параметра) |
|
Для функции: синтаксическая ошибка в аннотации _At_() (недопустимое имя параметра) |
|
Для функции: ReadableTo или WritableTo не содержало спецификацию ограничения в качестве параметра |
|
Количество внешних элементов в аннотации для функции превышает фактическое число параметров |
|
Постусловие null/notnull в deref уровня 0 не имеет смысла для функции |
|
Несовместимые типы операндов выражения для оператора |
|
Для первого объявления функции отсутствуют аннотации |
|
В аннотации обнаружен дополнительный оператор _Deref_ |
|
В аннотации обнаружен неоднозначный оператор _Deref_ |
|
Обнаружен неверно размещенный оператор _Notref_, применяемый к токену |
|
При синтаксическом анализе токена обнаружена ошибка. |
|
Аннотация описывает ситуацию, к которой неприменимы условия |
|
Аннотация описывает ситуацию, когда динамическое значение (переменная) не может использоваться в условии |