Declaration mismatch

Не сочетайтесь между объявлениями функции или объявлениями переменной

Описание

Этот дефект происходит, когда объявление функции или объявление переменной не совпадают с другими экземплярами функции или переменной.

Риск

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

Подобная проблема может произойти с несоответствием в объявлениях функции.

Фиксация

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

Иногда, несоответствия объявления могут произойти, потому что объявления затронуты предыдущими директивами предварительной обработки. Например, объявление происходит в макросе, и макрос задан на одном пути к включению, но неопределенный в другом. Эти несоответствия объявления могут быть хитрыми, чтобы отладить. Идентифицируйте расхождение между двумя путями к включению и зафиксируйте конфликтные макроопределения.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Выравнивания.

Примеры

развернуть все

file1.c

int foo(void) {
    return 1;
}

file2.c

double foo(void);

int bar(void) {
    return (int)foo();
}

В этом примере file1.c объявляет foo() как возврат целого числа. В file2.c, foo() объявляется как возврат двойного. Это различие повышает дефект на втором экземпляре foo в file2.

Коррекция — выравнивает функциональные возвращаемые значения

Одна возможная коррекция должна изменить объявления функции так, чтобы они соответствовали. В этом примере, путем изменения объявления foo в file2.c, чтобы совпадать с file1.c, фиксируется дефект.

file1.c

int foo(void) {
    return 1;
}

file2.c

int foo(void);

int bar(void) {
    return foo();
}

test1.c

#include<stdio.h>
#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

void func2();

int main(){ 
    square.side=1; 
    circle.radius=1;
    
    func2();
    return 0;
}

test2.c

#include<stdio.h>
#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square;

void func2(){ 
    printf("%d\n", square.side); 
    printf("%d\n", circle.radius);
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square;

В этом примере дефект несоответствия объявления повышен на square в test2.c, потому что Polyspace® выводит тот square в square.h не имеет того же выравнивания как square в test2.c. Эта ошибка происходит потому что #pragma pack(1) оператор в circle.h объявляет определенное выравнивание. В test2.c circle.h включен прежде square.h. Поэтому #pragma pack(1) оператор от circle.h не сбрасывается к выравниванию по умолчанию после aCircle структура. Из-за этого пропуска test2.c выводит что aSquare square структура также имеет выравнивание 1 байт.

Коррекция — закрывает операторы упаковки

Одна возможная коррекция должна сбросить выравнивание структуры после aCircle объявление struct. Для GNU® или компиляторов Microsoft® Visual, зафиксируйте дефект путем добавления #pragma pack() оператор в конце circle.h.

test1.c

#include<stdio.h>
#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

void func2();

int main(){ 
    square.side=1; 
    circle.radius=1;

    func2();
    return 0;
}

test2.c

#include<stdio.h>
#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square;

void func2(){ 
    printf("%d\n", square.side); 
    printf("%d\n", circle.radius);
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

#pragma pack()

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square;

Другие компиляторы требуют различного #pragma pack синтаксис. Для вашего синтаксиса см. документацию для своего компилятора.

Коррекция — использует Ignore pragma pack directives Опция

Одна возможная коррекция должна добавить Ignore pragma pack directives опция к вашему анализу Средства поиска Ошибки. Если вы хотите, чтобы выравнивание структуры изменилось для каждой структуры, и вы не хотите видеть этот дефект Declaration mismatch, использовать эту коррекцию.

  1. На панели Настройки выберите панель Advanced Settings.

  2. В поле Other введите -ignore-pragma-pack.

  3. Повторно выполните свой анализ.

    Дефект Declaration mismatch разрешен.

Проверяйте информацию

Группа: Программирование
Язык: C | C++
Значение по умолчанию: On
Синтаксис командной строки: DECL_MISMATCH
Удар: высоко
ID CWE: 685, 686
Введенный в R2013b