Вебинар: Парсим С++ - 25.10
Несколько раз нам писали пользователи, у которых перестал работать анализ части проектов. Общей особенностью было использование директивы '#import' в проблемных файлах. В данной заметке будет кратно описано, с чем связана проблема, и что делать для возобновления работы анализа.
Примечание. Данная заметка актуальна только для Windows при использовании компилятора 'cl.exe' для препроцессирования.
Для поиска ошибок в коде, написанном на языках C, C++, PVS-Studio использует препроцессированные файлы. Для их получения анализатор полагается на сторонние инструменты, в частности – на компилятор cl.exe. Для указания необходимости генерации препроцессированных файлов для cl.exe используется флаг '/P'.
Проблема заключается в том, что, начиная с версии Visual Studio 15.8 (и соответствующей версии Visual C++ - VC++ 2017 version 15.8 v14.15 toolset), при запуске cl.exe с флагом '/P' на файлах, содержащих директиву '#import', в компиляторе возникает ошибка.
При этом сборка (когда компилятору не передаётся флаг '/P') проходит успешно. Со стороны это может выглядеть примерно так: проект успешно собирается, но анализатор PVS-Studio не работает. Вывод анализатора на проблемных файлах будет примерно следующим:
c:\program files (x86)\microsoft visual
studio\2017\community\vc\tools\msvc\14.16.27023\include\comdef.h:
fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1518)
Internal Compiler Error in c:\program files (x86)\microsoft visual
studio\2017\community\vc\tools\msvc\14.16.27023\bin\hostx64\x64\cl.exe
Если вы столкнулись с такой проблемой, скорее всего, ваш проект использует Platform Toolset V141, и проблема возникла после обновления Visual Studio и соответствующих пакетов Visual C++ (и компилятора, соответственно) на более свежую версию. В итоге сборка проекта всё также проходит успешно, а вот анализ – нет.
Чтобы убедиться, что проблема действительно в компиляторе, можете попробовать выставить в настройках соответствующего проекта флаг '/P' и выполнить сборку. Выставление флага: Properties|C/C++|Preprocessor|Preprocess to a File -> Yes(/P).
Кстати, про эту проблему есть отдельная тема на форуме Visual Studio: https://developercommunity.visualstudio.com/content/problem/313306/vs2017-158-internal-compiler-error-msc1cpp-line-15-1.html
К сожалению, описанная проблема до сих пор актуальна, и будет исправлена, скорее всего, только в следующем релизе Visual Studio. Однако, вы можете продолжать использовать PVS-Studio для проверки проектов, затронутых данной проблемой, с помощью небольшого workaround'а.
При вызове компилятора для препроцессирования анализатором задаётся дополнительный макрос – 'PVS_STUDIO'. Используя этот макрос, вы можете обернуть проблемные строки кода директивой #ifdef - это позволит игнорировать их препроцессору, но при этом не затронет компиляцию кода. Как минимум, следует обернуть саму директиву '#import':
#if !defined(PVS_STUDIO)
#import
...
#endif
Обратите внимание, что в таком случае обёрнутая в директиву часть кода не попадёт в результирующие препроцессированные файлы. В большинстве случаев данная правка не должна повлиять на результаты анализа.
Примечание. Данная проблема была решена в версии компилятора в составе Visual Studio (2017) 15.9.14.
Вы можете откатиться на более старую версию компилятора (или более новую), в которой описанной выше проблемы нет (напоминаю, она появилась, начиная с VC++ 2017 Version 15.8 v14.15 toolset).
Заметьте, что Visual Studio 2017 позволяет устанавливать на систему несколько экземпляров Platform Toolset V141, что позволит, при желании, не уменьшать версию Platform Toolset в проекте.
Указать необходимые для использования версии компилятора можно в файлах <VsInstanceDir>\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.[txt|props], где <VsInstanceDir> - установочная директория конкретного выпуска Visual Studio.
0