Анализ показывает ошибку или предупреждение похожего на одно из этих сообщений об ошибке:
Declaration of [...] is incompatible with a declaration in another translation unit ([...])
Это сообщение появляется, когда конфликтные объявления не прибывают из того же заголовочного файла.
Когда одно из конфликтных объявлений находится в заголовочном файле.
Declaration of [...] had a different meaning during compilation of [...] ([...])
Это сообщение появляется, когда конфликтные объявления прибывают из того же заголовочного файла, включенного в файлы другого источника.
Ошибка указывает, что та же переменная или функция или тип данных объявляются по-другому в различных модулях перевода. Конфликтные объявления нарушают Одно Правило Определения (cf. Стандарт C++, ISO/IEC 14882:2003, Раздел 3.2). Когда конфликтные объявления происходят, Polyspace® Code Prover™ не выбирает объявление и продолжает анализ.
Общие наборы инструментальных средств компиляции часто не хранят информацию типа данных во время процесса соединения. Конфликтные объявления не вызывают ошибки с вашим компилятором. Polyspace Code Prover следует более строгим стандартам для соединения, чтобы гарантировать отсутствие определенных ошибок времени выполнения.
Идентифицировать первопричину ошибки:
Из сообщения об ошибке идентифицируйте эти два исходных файла с конфликтными объявлениями.
Например, сообщение об ошибке выглядит так сообщение:
C:\field.h, line 1: declaration of class "a_struct" had a different meaning during compilation of "file1.cpp" | struct a_struct { | | Detected during compilation of secondary translation unit "file2.cpp"
a_struct
имеет конфликтное объявление в file1.cpp
и file2.cpp
, оба из которых включают заголовочный файл field.h
.Альтернативное сообщение об ошибке может выглядеть так:
C:\field2.h, line 1: declaration of class "a_struct" had is incompatible with a declaration in another translation unit | the other declaration is at line 1 of field1.h" | struct a_struct { | | Detected during compilation of secondary translation unit "file2.cpp"
a_struct
имеет конфликтное объявление в field2.h
и field.h
. Заголовочный файл field2.h
включен в исходный файл file2.cpp
.Попытайтесь идентифицировать конфликтные объявления в исходных файлах.
В противном случае откройте модули перевода, содержащие эти файлы. Иногда, модули перевода или предварительно обработанные файлы показывают конфликтные объявления более ясно, чем исходные файлы потому что директивы препроцессору, такие как #include
и #define
операторы, заменяются соответственно, и макросы расширены.
Повторно выполните анализ с флагом -keep-relaunch-files
так, чтобы все модули перевода были сохранены. В пользовательском интерфейсе введите флаг для опции Other
.
Аналитические остановки после компиляции. Модули перевода или предварительно обработанные файлы хранятся в заархивированном файле ci.zip
в подпапке .relaunch
из папки результатов.
Разархивируйте содержимое ci.zip
.
Предварительно обработанные файлы имеют то же имя как исходные файлы. Например, предварительно обработанный файл с file1.cpp
назван file1.ci
.
Когда вы открываетесь, предварительно обработанные файлы в номерах строки утвердили в сообщении об ошибке, можно определить конфликтные объявления.
Объявление переменной не совпадает со своим определением. Например:
Объявление и определение используют различные типы данных.
Переменная объявлена столь же со знаком, но задана как без знака.
Объявление и определение используют спецификаторы другого типа.
Переменная объявлена как массив, но задана как непеременная типа массив.
Для переменной типа массив объявление и определение используют различные размеры массивов.
В этом примере код показывает соединяющуюся ошибку из-за несоответствия в спецификаторах типа. Объявление в file1.c
не использует спецификаторы типа, но определение в file2.c
использует volatile
спецификатор.
file1.c | file2.c |
---|---|
extern int x; void main(void) {/* Variable x used */} | volatile int x; |
В этих случаях можно обычно определять различие путем рассмотрения исходных файлов. Вы не должны видеть предварительно обработанные файлы.
Убедитесь, что объявление переменной совпадает со своим определением.
Объявление функции не совпадает со своим определением. Например:
Объявление и определение используют различные типы данных в аргументах или возвращаемых значениях.
Объявление и определение используют различное количество аргументов.
Функция аргумента переменной или varargs объявляется в одной функции, но это называется в другой функции без предыдущего объявления.
В этом случае сообщение об ошибке утверждает, что необходимый прототип для функции отсутствует.
В этом примере код показывает соединяющуюся ошибку из-за несоответствия в типе возврата. Объявление в file1.c
имеет возвращаются, вводят int
, но определение в file2.c
имеет возвращаются, вводят float
.
file1.c | file2.c |
---|---|
int input(void); void main() { int val = input(); } | float input(void) { float x = 1.0; return x; } |
В этих случаях можно обычно находить различие путем рассмотрения исходных файлов. Вы не должны видеть предварительно обработанные файлы.
Убедитесь, что объявление функции совпадает со своим определением.
Даже если ваш процесс сборки позволяет эти ошибки, у вас могут быть неожиданные результаты в течение времени выполнения. Если объявление функции и определение с конфликтными прототипами существуют в вашем коде, когда вы вызываете функцию, результат может быть неожиданным.
Для аргумента переменной или функции varargs, объявите функцию, прежде чем вы вызовете его. Если вы не хотите изменять свой исходный код, можно работать вокруг этой ошибки соединения.
Добавьте объявление функции в отдельном файле.
Только в целях верификации, #include
этот файл в каждом исходном файле при помощи опции Include (-include)
.
Вы используете то же имя идентификатора в двух несвязанных объектах. Это некоторые общие причины несвязанных объектов в том же проекте Polyspace:
Вы намеревались объявить объекты static
так, чтобы они не имели внешнего рычажного устройства, но не использовали static
спецификатор.
Вы объявили тот же объект в нескольких исходных файлах вместо того, чтобы поместить объявление в заголовочный файл и включая в исходных файлах.
Вы создали проект Polyspace из команды сборки с помощью polyspace-configure
команда. Команда сборки создала несколько независимых двоичных файлов, но файлы, вовлеченные во все двоичные файлы, были собраны в одном проекте Polyspace.
В зависимости от первопричины для несвязанных объектов с помощью того же имени используйте соответствующее решение.
Если ваш проект Polyspace был создан из команды сборки, и исходные файлы для независимых двоичных файлов собрались, разделите проект в модули при трассировке команды сборки. Смотрите polyspace-configure
.
Определение переменной зависит от макроса, задаваемого ранее. Один исходный файл задает макрос, в то время как другой не делает, вызывая конфликты в определениях переменной.
В этом примере, file1.cpp
и file2.cpp
включайте заголовочный файл field.h
. Заголовочный файл задает структуру a_struct
это зависит от макроопределения. Только один из этих двух файлов, file2.cpp
, задает макро-DEBUG
. Определение a_struct
в модуле перевода с file1.cpp
отличается от определения в модуле с file2.cpp
.
file1.cpp | file2.cpp |
---|---|
#include "field.h" int main() { a_struct s; init_a_struct(&s); return 0; } | #define DEBUG #include <string.h> #include "field.h" void init_a_struct(a_struct* s) { memset(s, 0, sizeof(*s)); } |
struct a_struct { int n; #ifdef DEBUG int debug; #endif }; |
Когда вы открываете предварительно обработанные файлы file1.ci
и file2.ci
, вы видите конфликтные объявления.
file1.ci | file2.ci |
---|---|
struct a_struct { int n; }; | struct a_struct { int n; int debug; }; |
Избегайте макрозависимых определений. В противном случае зафиксируйте соединяющиеся ошибки. Убедитесь, что макрос или задан или не определен на всех путях, которые содержат определение переменной.
Ключевое слово переопределено как макрос, но не во всех файлах.
В этом примере, bool
ключевое слово в file1.cpp
, но это переопределено как макрос в file2.cpp
.
file1.cpp | file2.cpp |
---|---|
#include "bool.h" int main() { return 0; } | #define false 0 #define true (!false) #include "bool.h" |
template <class T> struct a_struct { bool flag; T t; a_struct() { flag = true; } }; |
Будьте сопоставимы со своим использованием ключевого слова в программе. Используйте ключевое слово, заданное в стандартном заголовке библиотеки, или используйте вашу переопределенную версию.
#pragma pack(n)
оператор изменяет выравнивание упаковки структуры, но не во всех файлах. См. также #pragma Директивы (Polyspace Code Prover).
В этом примере выравнивание упаковки значения по умолчанию используется в file1.cpp
, но #pragma pack(1)
оператор осуществляет выравнивание упаковки 1 байта в file2.cpp
.
file1.cpp | file2.cpp |
---|---|
int main() { return 0; } | #pragma pack(1) #include "pack.h" |
struct a_struct { char ch; short sh; }; |
Введите #pragma pack(n)
оператор в заголовочном файле так, чтобы это применилось ко всем исходным файлам, которые включают заголовок.