exponenta event banner

CERT C: Rec. DCL23-C

Гарантия уникальности взаимно видимых идентификаторов

Описание

Определение правила

Убедитесь, что взаимно видимые идентификаторы уникальны. [1 ]

Внедрение Polyspace

Эта проверка проверяет наличие следующих проблем:

  • Внешние идентификаторы не различаются.

  • Идентификатор в одной области и пространстве имен не отличается.

  • Идентификатор макроса не отличается.

  • Имя макросов и идентификаторов не отличается.

Примеры

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

Проблема

Проблема возникает, когда внешние идентификаторы имеют одни и те же первые шесть символов для C90 или те же первые 31 символ для C99.

Проверка не помечает эту проблему в анализе Polyspace ® по умолчанию в качестве кода. См. раздел Шашки, деактивированные в Polyspace как анализ кода по умолчанию (Polyspace Bug Finder Access).

Риск

Внешние идентификаторы объявлены с глобальной областью или классом хранения extern.

Polyspace рассматривает два имени как отдельные, если есть разница между их первыми 31 символами. Если разница между двумя именами возникает только за пределами первых 31 символа, их можно легко принять друг за друга. Читаемость кода снижается. Для C90 разница должна возникать между первыми шестью символами. Для проверки правил C90 используйте значение c90 для опции C standard version (-c-version).

Пример - C90: первые шесть символов идентификаторов не уникальны
int engine_temperature_raw;
int engine_temperature_scaled;   /* Non-compliant */					
int engin2_temperature;          /* Compliant */	

В этом примере идентификатор engine_temperature_scaled имеет те же первые шесть символов, что и предыдущий идентификатор, engine_temperature_raw.

Пример - C99: Первые 31 символ идентификаторов не уникальны
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.

Пример - C90: Первые шесть идентификаторов символов в различных единицах перевода отличаются в одном регистре
/* file1.c */
int abc = 0;
/* file2.c */
int ABC = 0; /* Non-compliant */

В этом примере реализация поддерживает шесть значимых символов без учета регистра во внешних идентификаторах. Идентификаторы в двух переводах различны, но не отличаются своими значимыми символами.

Проблема

Проблема возникает, когда вы объявляете идентификаторы в той же области и пространстве имен, а идентификаторы имеют те же первые 31 символ в C90 или те же первые 63 символа в C99.

Риск

Polyspace рассматривает два имени как отдельные, если есть разница между их первыми 63 символами. Если разница между двумя именами возникает только за пределами первых 63 символов, их можно легко принять друг за друга. Читаемость кода снижается. Для C90 разница должна быть между первыми 31 символами. Для проверки правил C90 используйте значение c90 для опции C standard version (-c-version).

Пример - C90: Первые 31 символ идентификаторов не уникальны
extern int engine_exhaust_gas_temperature_raw;
static int engine_exhaust_gas_temperature_scaled;      /* Non-compliant */

extern double engine_exhaust_gas_temperature_raw;
static double engine_exhaust_gas_temperature2_scaled;  /* Compliant */

void func ( void )
{
  /* Not in the same scope */
  int engine_exhaust_gas_temperature_local;            /* Compliant */
}

В этом примере идентификатор engine_exhaust_gas_temperature_scaled имеет тот же 31 символ, что и предыдущий идентификатор, engine_exhaust_gas_temperature_raw.

Правило не применяется, если два идентификатора имеют одинаковый 31 символ, но разные области. Например, engine_exhaust_gas_temperature_local имеет тот же 31 символ, что и engine_exhaust_gas_temperature_raw но разная сфера охвата.

Пример - C99: Первые 63 символа идентификаторов не уникальны
extern int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_raw;
static int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_scale;
    /* Non-compliant */

extern int engine_gas_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx__raw;
static int engine_gas_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx__scale;
    /* Compliant */

void func ( void )
{
/* Not in the same scope */
    int engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_local;
          /* Compliant */
}

В этом примере идентификатор engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_scale имеет те же 63 символа, что и предыдущий идентификатор, engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_x_raw.

Проблема

Проблема возникает при использовании идентификаторов макросов, которые имеют один и тот же первый 31 символ в C90 или тот же первый 63 символа в C99.

Риск

Имена идентификаторов макросов должны отличаться от других идентификаторов макросов и их параметров.

Polyspace рассматривает два имени как отдельные, если есть разница между их первыми 63 символами. Если разница между двумя именами возникает только за пределами первых 63 символов, их можно легко принять друг за друга. Читаемость кода снижается. Для C90 разница должна быть между первыми 31 символами. Для проверки правил C90 используйте значение c90 для опции C standard version (-c-version).

Пример - C90: Первые 31 символ имен макросов не уникальны
#define engine_exhaust_gas_temperature_raw egt_r
#define engine_exhaust_gas_temperature_scaled egt_s   /* Non-compliant */

#define engine_exhaust_gas_temp_raw egt_r
#define engine_exhaust_gas_temp_scaled egt_s          /* Compliant */

В этом примере макрос engine_exhaust_gas_temperature_scaled egt_s имеет тот же первый 31 символ, что и предыдущий макрос engine_exhaust_gas_temperature_scaled.

Пример - C99: Первые 63 символа имен макросов не уникальны

#define engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw egt_r
#define engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw_scaled egt_s
    /* Non-compliant */

/* 63 significant case-sensitive characters in macro identifiers */
#define new_engine_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_raw egt_r
#define new_engine_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_scaled egt_s
    /* Compliant */

В этом примере макрос engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___gaz_scaled имеет те же первые 63 символа, что и предыдущий макрос engine_xxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx_xxxxxxxxx___raw.

Проблема

Проблема возникает, когда идентификаторы не отличаются от имен макросов.

Риск

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

Polyspace рассматривает два имени как отдельные, если есть разница между их первыми 63 символами. Если разница между двумя именами возникает только за пределами первых 63 символов, их можно легко принять друг за друга. Читаемость кода снижается. Для C90 разница должна быть между первыми 31 символами. Для проверки правил C90 используйте значение c90 для опции C standard version (-c-version).

Пример - Имена макросов совпадают с именами идентификаторов
#define Sum_1(x, y) ( ( x ) + ( y ) )
short Sum_1;                    /* Non-compliant */

#define Sum_2(x, y) ( ( x ) + ( y ) )
short x = Sum_2 ( 1, 2 );       /* Compliant */

В этом примере: Sum_1 является как именем идентификатора, так и макросом. Sum_2 используется только в качестве макроса.

Пример - C90: Первые 31 символ имени макроса совпадает с именем идентификатора
#define	   low_pressure_turbine_temperature_1 lp_tb_temp_1
static int low_pressure_turbine_temperature_2;	  /* Non-compliant  */	

В этом примере идентификатор low_pressure_turbine_temperature_2 имеет тот же первый 31 символ, что и предыдущий макрос low_pressure_turbine_temperature_1.

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

Группа: Rec. 02. Объявления и инициализация (DCL)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОНА И/ИЛИ ЕГО ПРОГРАММНОГО ИНЖЕНЕРНОГО ИНСТИТУТА, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ КАК ЕСТЬ. УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБЫХ ВОПРОСОВ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ ТОВАРНОЙ ПРИГОДНОСТИ, ИСКЛЮЧИТЕЛЬНОСТИ ИЛИ РЕЗУЛЬТАТОВ, ПОЛУЧЕННЫХ ОТ ИСПОЛЬЗОВАНИЯ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.