Бесплатная статическая проверка для кода C99
Я ищу бесплатную статическую проверку для кода C99 (включая расширения GCC) с возможностью явного указания "эти макросы препроцессора всегда определены".
Мне нужна эта последняя часть, потому что я компилирую встроенный код для одного целевого процессора. Компилятор (Microchip C32, GCC based) устанавливает макрос на основе выбранного процессора, который затем используется в заголовочных файлах PIC32, чтобы выбрать соответствующий заголовочный файл для конкретного процессора. cppcheck поэтому терпит неудачу, потому что он обнаруживает 30 разных #ifdef
, используемых для выбора одного из многих возможных процессоров PIC32, пытается проанализировать все возможные комбинации из них плюс все остальные #define
s, и терпит неудачу.
Например, если splint может обрабатывать код C99, я бы использовал
splint -D__PIC32_FEATURE_SET__=460 -D__32MX460F512L__ \
-D__LANGUAGE_C__ -I/path/to/my/includes source.c
Еще одна проблема заключается в том, что компилятор PIC32 toolchain называется pic32-gcc
, а не только gcc
, хотя мне еще не дошло, что нужно учитывать это.
Обновление # 1. Меня интересует только одно, но является ортогональным этому вопросу, это интеграция Eclipse (было бы неплохо не писать makefile для 30 + компиляционных модулей). Я спросил об этом на форумах Eclipse (хотя в обсуждении больше говорится об интеграции в Eclipse). Ничего не примечательного.
Обновить # 2 - просто попробовал scan-build
из clang, используя:
scan-build --use-cc=/usr/local/bin/pic32-gcc make -B -k all
... (также без флага --use-cc
), но все, что я получил, это типичный вывод сборки, примером которого является:
Building file: ../src/MoreMath.c
Invoking: PIC C32 C Compiler
pic32-gcc -D__DEBUG -I/usr/local/pic32-libs/include -O0 -Wall -c -fmessage-length=0 -std=gnu99 -Werror-implicit-function-declaration -MMD -MP -MF"src/MoreMath.d" -MT"src/MoreMath.d" -mprocessor=32MX460F512L -D__DEBUG -g -o"src/MoreMath.o" "../src/MoreMath.c"
Finished building: ../src/MoreMath.c
... и в конце:
Building target: MyBinary.elf
Invoking: PIC C32 C Linker
pic32-gcc -Wl,-Map,MyBinary.map -mprocessor=32MX460F512L --defsym=__MPLAB_DEBUG=1 -o"MyBinary.elf" <<ALL OF MY *.o FILES HERE>>
Finished building target: MyBinary.elf
scan-build: Removing directory '/tmp/scan-build-2010-06-21-1' because it contains no reports.
Таким образом, либо мой код идеален в соответствии с scan-build
, либо он ничего не делает. Я не уверен, какой хороший тест может быть, если он работает.
Ответы
Ответ 1
Статический анализатор Clang должен работать.
Другой вариант с исходным кодом #defines
заключается в том, что вы можете запустить cpp
по исходному коду с некоторыми инструкциями препроцессора, а затем запустить этот результирующий код через статический анализатор.
Ответ 2
Вы можете просто добавить такой код в верхнюю часть заголовка, который гарантирует, что он определен:
#ifndef MACRO_I_NEED
#error "MACRO_I_NEED should be defined"
#define MACRO_I_NEED // to appease cppcheck
#endif
Ответ 3
Вместо использования scan-build с clang, рассмотрите возможность замены gcc вообще! Поддержка Clang C стабильна (и делает все возможное, чтобы эмулировать gcc), и должна отлично обрабатывать ваш код.
Попробуйте что-нибудь вроде make -j3 CC=clang
и посмотрите, что произойдет!
PS. Этот синтаксис может быть совершенно неправильным. Не использовали make файлы в возрасте (CMake потрясающе кстати).
Ответ 4
В зависимости от того, какие фактические анализы вы хотите использовать в своем коде, вы можете взглянуть на Frama-C. Он использует любой препроцессор C, о котором вы ему рассказываете, поэтому вы можете использовать PIC32 CPP, если хотите.
Ответ 5
Это может не дать вам прямое решение, но вы можете подумать о том, чтобы взглянуть на Coverity, который является проприетарным статическим синтаксическим анализатором, но это бесплатно для проектов ОС. Он должен выполнять работу, связанную с вашими потребностями!
Ура!
Ответ 6
Вы можете использовать инструмент, например sunifdef, чтобы частично препроцитировать исходный код в соответствии с предполагаемыми определенными макросами. Вам придется создавать копии системных и библиотечных заголовков, на которые влияют эти определения и обрабатывать их. Затем при выполнении статического анализа вы указываете другой путь include, указывающий на уже обработанные заголовки.