Объявление одной и той же функции или объекта несовместимыми способами
Эта проверка деактивируется в анализе Polyspace ® по умолчанию в качестве кода. См. раздел Шашки, деактивированные в Polyspace как анализ кода по умолчанию (Polyspace Bug Finder Access).
Объявление одной и той же функции или объекта несовместимыми способами. [1 ]
Эта проверка проверяет наличие следующих проблем:
Неразличимые имена внешних идентификаторов.
Несоответствие декларации.
Проблема возникает, когда внешние идентификаторы не отличаются.
Внешние идентификаторы объявлены с глобальной областью или классом хранения extern.
Polyspace рассматривает два имени как отдельные, если есть разница между их первыми 31 символами. Если разница между двумя именами возникает только за пределами первых 31 символа, их можно легко принять друг за друга. Читаемость кода снижается. Для C90 разница должна быть между первыми 6 символами. Для проверки правил C90 используйте значение c90 для опции C standard version (-c-version).
int engine_temperature_raw; int engine_temperature_scaled; /* Non-compliant */ int engin2_temperature; /* Compliant */
В этом примере идентификатор engine_temperature_scaled имеет те же первые шесть символов, что и предыдущий идентификатор, engine_temperature_raw.
int engine_exhaust_gas_temperature_raw; int engine_exhaust_gas_temperature_scaled; /* Non-compliant */ int eng_exhaust_gas_temp_raw; int eng_exhaust_gas_temp_scaled; /* Compliant */
В этом примере идентификатор engine_exhaust_gas_temperature_scaled имеет тот же первый 31 символ, что и предыдущий идентификатор, engine_exhaust_gas_temperature_raw.
/* file1.c */ int abc = 0;
/* file2.c */ int ABC = 0; /* Non-compliant */
В этом примере реализация поддерживает 6 значимых символов без учета регистра во внешних идентификаторах. Идентификаторы в двух трансляциях различны, но не отличаются своими значимыми символами.
Несоответствие объявлений происходит, когда объявление функции или переменной не соответствует другим экземплярам функции или переменной.
Когда происходит несоответствие между двумя объявлениями переменных в различных единицах компиляции, типичный компоновщик следует алгоритму выбора одного объявления для переменной. Если ожидается объявление переменной, отличное от выбранного компоновщиком, при использовании переменной можно увидеть неожиданные результаты.
Подобная проблема может возникнуть при несоответствии описаний функций.
Исправление зависит от типа несоответствия объявления. Если оба объявления действительно ссылаются на один и тот же объект, используйте одно и то же объявление. Если объявления ссылаются на различные объекты, измените имена одной из переменных. При изменении имени переменной не забудьте изменить ее во всех местах, где используется переменная.
Иногда могут возникать несоответствия в объявлениях, поскольку на них влияют предыдущие директивы предварительной обработки. Например, объявление происходит в макросе, и макрос определяется на одном пути включения, но не определяется в другом. Эти несоответствия объявлений могут быть сложны для отладки. Определите расхождение между двумя путями включения и исправьте конфликтующие определения макросов.
Если вы не хотите устранять проблему, добавьте комментарии к результату или коду, чтобы избежать другой проверки. См. раздел Результаты анализа пространства адресов с помощью исправлений ошибок или обоснований.
file1.c
int foo(void) {
return 1;
}file2.c
double foo(void);
int bar(void) {
return (int)foo();
}В этом примере файл 1.c объявляет foo() как возвращающее целое число. В файле 2.c, foo() объявлен как возвращающий двойник. Эта разница вызывает дефект во втором экземпляре foo в файле 2.
Одной из возможных корректировок является изменение описаний функций таким образом, чтобы они совпадали. В этом примере путем изменения объявления 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 "square.h"
#include "circle.h"
struct aCircle circle;
struct aSquare square;
int main(){
square.side=1;
circle.radius=1;
return 0;
} | test2.c #include "circle.h"
#include "square.h"
struct aCircle circle;
struct aSquare square;
int main(){
square.side=1;
circle.radius=1;
return 0;
} |
circle.h #pragma pack(1)
extern struct aCircle{
int radius;
} circle; | square.h extern struct aSquare {
unsigned int side:1;
} square; |
В этом примере возникает дефект несоответствия объявления square в square.h, потому что Polyspace делает вывод, что square в square.h не имеет того же выравнивания, что и square в test2.c. Эта ошибка возникает из-за #pragma pack(1) оператор circle.h объявляет конкретную центровку. В тесте 2.c circle.h включается перед square.h. Следовательно, #pragma pack(1) оператор circle.h не сбрасывается на выравнивание по умолчанию после aCircle структура. Из-за этого пропуска, test2.c делает вывод, что aSquare square структура также имеет выравнивание 1 байт.
Одной из возможных корректировок является сброс выравнивания структуры после aCircle объявление структуры. Для компиляторов GNU ® или Microsoft ® Visual исправьте дефект, добавив #pragma pack() заявление в конце circle.h.
test1.c #include "square.h"
#include "circle.h"
struct aCircle circle;
struct aSquare square;
int main(){
square.side=1;
circle.radius=1;
return 0;
} | test2.c #include "circle.h"
#include "square.h"
struct aCircle circle;
struct aSquare square;
int main(){
square.side=1;
circle.radius=1;
return 0;
} |
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 для анализа Bug Finder. Если требуется изменить выравнивание структуры для каждой структуры и не требуется видеть дефект несоответствия объявления, используйте эту поправку.
На панели Конфигурация (Configuration) выберите панель Дополнительные параметры (Advanced Settings).
В поле «Прочее» введите -ignore-pragma-pack.
Повторите анализ.
Устранен дефект несоответствия декларации.
| Разрешимость: Разрешимая |
[1] Выдержки из стандарта «ISO/IEC TS 17961 Technical Specification - 2013-11-15» воспроизводятся с согласия AFNOR. Нормативную ценность имеет только оригинальный и полный текст стандарта, опубликованный изданиями AFNOR - доступный через веб-сайт www.boutique.afnor.org.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.