Неопределенная ошибка идентификатора

Проблема

Polyspace® на фазе компиляции не выполняется верификация с сообщением о неопределенных идентификаторах.

Сообщение указывает, что Polyspace не может найти определение переменной. Поэтому он не может идентифицировать тип переменной.

Возможная причина: отсутствующие файлы

Указанный исходный код не содержит определения переменной. Например, переменная определяется в файле включения, который Polyspace не может найти.

Если вы #include-d файл включения в исходный код, но не добавил его к своему проекту Polyspace, вы видите предыдущее предупреждение:

Warning: could not find include file "my_include.h"

Решение

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

Возможная причина: непризнанное ключевое слово

Переменная представляет ключевое слово, которое распознает ваш компилятор, но не является частью ANSI® Стандарт C. Поэтому Polyspace его не распознает.

Например, некоторые компиляторы интерпретируют __SP как ссылка на указатель стека.

Решение

Если переменная представляет ключевое слово, которое Polyspace не распознает, замените или удалите ключевое слово из исходного кода или предварительно обработанного кода.

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

  • Замените или удалите каждое отдельное неизвестное ключевое слово с помощью опции анализа. Замените ключевое слово для компилятора эквивалентным ключевым словом от ANSI C Standard.

    Для получения информации об опции анализа смотрите Preprocessor definitions (-D).

  • Объявите неизвестные ключевые слова в отдельном заголовочном файле с помощью #define директивы. Укажите заголовочный файл с помощью опции анализа.

    Для получения информации об опции анализа смотрите Include (-include). Для примера файла заголовка смотрите Собирать опции компиляции Эффективно.

Возможная причина: декларация, встроенная в #ifdef Операторы

Переменная объявлена в ветви # ifdef macro_name директива препроцессора. Например, объявление переменной max_power происходит следующим образом:

#ifdef _WIN32
  #define max_power 31
#endif

Ваш набор инструментов компиляции может рассмотреть макрос macro_name как неявно определено и выполнить #ifdef ветвь. Однако компиляция Polyspace может не рассматривать макрос как заданный. Поэтому #ifdef ветвь не выполняется, и переменная max_power не объявляется.

Решение

Чтобы обойти ошибку компиляции, выполните одно из следующих действий:

  • Используйте Target & Compiler опции, чтобы непосредственно задать компилятор. Например, чтобы эмулировать Visual C++® компилятор, установите Compiler равным visual12.0. См. «Цель» и «Компилятор».

  • Определите макрос явным образом с помощью опции Preprocessor definitions (-D).

Примечание

Если вы создаете Polyspace путем трассировки команд сборки, большинство Target & Compiler опций устанавливаются автоматически.

Возможная причина: Проект, созданный из Non-Debug Build

Это может быть возможной причиной, только если неопределенный идентификатор встречается в assert оператор (или эквивалентный макрос Visual C++, такой как ASSERT или VERIFY).

Как правило, эта ошибка встречается следующим образом. Вы создаете проект Polyspace из системы сборки в неотладке. Когда вы запускаете анализ на проекте, вы сталкиваетесь с ошибкой компиляции из неопределенного идентификатора в assert оператор. Вы находите, что идентификатор my_identifier определяется в #ifndef NDEBUG оператор, например, следующим образом:

#ifndef NDEBUG
int my_identifier;
#endif

Стандарт C утверждает, что когда NDEBUG макрос определен, все операторы assert должны быть отключены.

Большинство IDE определяют NDEBUG макрос в их системах сборки. Когда вы создаете свой исходный код в IDE в неотладке, кодируете в #ifndef NDEBUG оператор удаляется во время предварительной обработки. Например, в предыдущем примере my_identifier не определен. Если my_identifier происходит только в операторах assert, также не используется, потому что NDEBUG отключает операторы assert. У вас нет ошибок компиляции из неопределенных идентификаторов, и ваша система сборки успешно выполняется.

Polyspace не отключает assert операторы, даже если NDEBUG макрос определен, потому что программное обеспечение использует assert операторы для усиления верификации.

Когда вы создаете проект Polyspace из системы сборки, если ваша система сборки определяет NDEBUG макрос, он также определен для вашего проекта Polyspace. Polyspace удаляет код в #ifndef NDEBUG оператор во время предварительной обработки, но не отключает assert операторы. Если assert операторы в коде полагаются на код в #ifndef NDEBUG оператор, могут возникнуть ошибки компиляции.

В предыдущем примере:

  • Определение my_identifier удаляется во время предварительной обработки.

  • assert операторы не отключены. Когда my_identifier используется в assert оператор, вы получите ошибку из-за неопределенного идентификатора my_identifier.

Решение

Чтобы решить эту проблему, создайте проект Polyspace из системы сборки в режиме отладки. Когда вы выполняете систему сборки в режиме отладки, NDEBUG не определен. Когда вы создаете проект Polyspace из этой сборки, NDEBUG не определен для вашего проекта Polyspace.

В зависимости от настроек проекта используйте опцию, которая включает создание в режиме отладки. Например, если ваша система сборки gcc-based, можно задать DEBUG макро- и неопределенные NDEBUG:

gcc -DDEBUG=1 -UNDEBUG *.c

Также можно отключить assert операторы в предварительно обработанном коде с помощью опции Preprocessor definitions (-D). Однако Polyspace не сможет эмулировать assert операторы.