Каков лучший инструмент командной строки для очистки кода?

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

Кто-нибудь знает хороший инструмент?

Ответ 1

Как отметил Дэн Фего, GCC может перехватывать неиспользуемые переменные и неиспользуемые статические функции. Обычно он не находит неиспользуемые функции extern, поскольку он обычно работает с одним исходным файлом за раз.

GCC (v4.3.2) имеет сотни, если не тысячи вариантов. Одним из способов, которые могут помочь, является "--combine" для объединения исходных файлов (если у вас нет привычки помещать одну и ту же функцию или имена переменных внутри разных исходных файлов).

Опция '--help' сообщает вам больше; опции "--help=optimizers" и "--help=warnings" дают вам пару сотен строк вывода. Предупреждения включают:

-Wunused                    This switch lacks documentation
-Wunused-function           Warn when a function is unused
-Wunused-label              This switch lacks documentation
-Wunused-macros             Warn about macros defined in the main file that
                            are not used
-Wunused-parameter          Warn when a function parameter is unused
-Wunused-value              Warn when an expression value is unused
-Wunused-variable           Warn when a variable is unused

Добавлено: это script, называемый glint, который я использую для дезинфекции моего кода. Он довольно старый, поэтому он не использует обозначение "#!/bin/sh" для первой строки, и вместо ""[email protected]"" он говорит "$*", оба из которых должны быть исправлены, но не нужно фиксировать срочно. Обратите внимание, что хотя GCC 4.x больше не поддерживает параметр "-fwriteable-strings", он по-прежнему поддерживает параметр "-Wwrite-strings" и имеет значение.

Этот script демонстрирует, что вы можете получить много пробега из существующих инструментов с небольшим количеством работы. Вы можете сконфигурировать почти все используемые им параметры - хотя главным образом через среду, а не в командной строке. Конечно, вы можете добавить дополнительные параметры предупреждения в командную строку; то, что вы не можете сделать, это удалить предопределенные параметры, кроме как через среду. Но это нормально; они выбраны по умолчанию по уважительным причинам. В эти дни я, вероятно, установил бы "GLINT_ANSI=-std=c99" или исправлю script; Я не использую это в последнее время, так как я довольно точно кодирую стандарт, который обеспечивает glint. (Обратите внимание, что '-o /dev/null' означает, что вы можете делать только один файл за раз, взломать исправление!)

:   "@(#)$Id: glint.sh,v 1.5 2002/08/09 21:40:52 jleffler Exp jleffler $"
#
#   Use GCC as excruciatingly pedantic lint
#   Not a complete replacement for lint -- it doesn't do inter-file checking.
#   Now configurable via the environment.
#   Use GLINT_EXTRA_FLAGS to set extra flags via the environment.
#   NB: much Solaris code won't work with -undef enabled.

: ${GLINT_GCC:='gcc'}

: ${GLINT_ANSI='-ansi'}
: ${GLINT_FNO_COMMON='-fno-common'}
: ${GLINT_FSHORT_ENUMS='-fshort-enums'}
: ${GLINT_PEDANTIC='-pedantic'}
: ${GLINT_UNDEF='-undef'}
: ${GLINT_W='-W'}
: ${GLINT_WAGGREGATE_RETURN='-Waggregate-return'}
: ${GLINT_WALL='-Wall'}
: ${GLINT_WCAST_ALIGN='-Wcast-align'}
: ${GLINT_WCAST_QUAL='-Wcast-qual'}
: ${GLINT_WCONVERSION='-Wconversion'}
: ${GLINT_WMISSING_DECLARATIONS='-Wmissing-declarations'}
: ${GLINT_WREDUNDANT_DECLS='-Wredundant-decls'}
: ${GLINT_WMISSING_PROTOTYPES='-Wmissing-prototypes'}
: ${GLINT_WNESTED_EXTERNS='-Wnested-externs'}
: ${GLINT_WPOINTER_ARITH='-Wpointer-arith'}
: ${GLINT_WSHADOW='-Wshadow'}
: ${GLINT_WSTRICT_PROTOTYPES='-Wstrict-prototypes'}
: # ${GLINT_WTRADITIONAL='-Wtraditional'}
: ${GLINT_WWRITE_STRINGS='-Wwrite-strings'}

exec ${GLINT_GCC} \
    ${GLINT_ANSI} \
    ${GLINT_FNO_COMMON} \
    ${GLINT_FSHORT_ENUMS} \
    ${GLINT_PEDANTIC} \
    ${GLINT_UNDEF} \
    ${GLINT_WAGGREGATE_RETURN} \
    ${GLINT_WALL} \
    ${GLINT_WCAST_ALIGN} \
    ${GLINT_WCAST_QUAL} \
    ${GLINT_WCONVERSION} \
    ${GLINT_WMISSING_DECLARATIONS} \
    ${GLINT_WREDUNDANT_DECLS} \
    ${GLINT_WMISSING_PROTOTYPES} \
    ${GLINT_WNESTED_EXTERNS} \
    ${GLINT_WPOINTER_ARITH} \
    ${GLINT_WSHADOW} \
    ${GLINT_WSTRICT_PROTOTYPES} \
    ${GLINT_WTRADITIONAL} \
    ${GLINT_WWRITE_STRINGS} \
    ${GLINT_W} \
    ${GLINT_EXTRA_FLAGS} \
    -o /dev/null -O4 -g -c $*

Ответ 2

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

Ответ 3

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

  • Splint: я часто использую Splint, потому что он доступен для многих дистрибутивов GNU/Linux, С этим относительно легко работать; однако он имеет тенденцию быть подавляющим при работе в строжайшей обстановке. Более того, иногда необходимое использование аннотаций может загромождать и обфускивать легко читаемый код. Независимо от того, я предлагаю использовать его.

  • Uno: Uno определенно является многообещающим, но это не так строго, как Splint (по дизайну). Вместо этого он фокусируется на ясности и полезности своих предупреждений. Для меня Uno полезен только в качестве дополнения к Splint (чтобы четко указать предупреждения, скрытые среди сравнительно многих проблем Splint).

  • PC-lint: Я считаю, что PC-lint является громоздким для проприетарной программы. Я когда-то использовал его при разработке для MS-DOS и загадочных имен, которые он использует для своих ошибок, сделало его очень трудным для использования. Из того, что я слышу, есть много лучших продуктов для использования в MS-DOS.

  • Pscan: (мертвая гиперссылка) Pscan отлично подходит для поиска уязвимостей строки формата! Как и в случае с Uno, я предлагаю использовать его в качестве дополнения к Splint.

Если вы не работаете с C, вы также можете проверить: Wikipedia - List инструментов для анализа статического кода, Инструменты проверки/проверки, исходный/двоичный код Статические анализаторы и Анализаторы безопасности исходного кода.

Ответ 4

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

Ответ 5

splint (http://www.splint.org/) является превосходным; Я использовал его для мегалиновых кодов, чтобы искать такие вещи,

(Обновлено: все хотят быть арт-директором.)

Ответ 6

Как использовать профайлер и найти, какой код работает больше всего, и сосредоточиться на этих частях.

Может быть gprof может помочь?

/Johan

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