CERT C: Rule EXP39-C

Не получайте доступ к переменной через указатель несовместимого типа

Описание

Управляйте определением

Не получайте доступ к переменной через указатель несовместимого типа. [1]

Примеры

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

Описание

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

Риск

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

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

Исключение: можно преобразовать указатель на тип объекта в указатель на один из следующих типов:

  • char

  • signed char

  • unsigned char

Пример - несовместимый: бросьте к указателю, указывающему на объект более широкого типа

signed   char *p1;
unsigned int *p2;

void foo(void){ 
  p2 = ( unsigned int * ) p1;     /* Non-compliant */				
}

В этом примере, p1 может указать на signed char объект. Однако p1 брошен к указателю, который указывает на объект более широкого типа, unsigned int.

Пример - несовместимый: бросьте к указателю, указывающему на объект более узкого типа

extern unsigned int read_value ( void );
extern void display ( unsigned int n );

void foo ( void ){
  unsigned int u = read_value ( );
  unsigned short *hi_p = ( unsigned short * ) &u;    /* Non-compliant  */	
  *hi_p = 0;                                         
  display ( u );                                     
}

В этом примере, u unsigned int переменная. &u брошен к указателю, который указывает на объект более узкого типа, unsigned short.

На машине с обратным порядком байтов, операторе *hi_p = 0 попытки очистить высокие биты ячейки памяти, что &u точки к. Но, от результата display(u), вы можете найти, что высокие биты не были очищены.

Пример - совместимый: бросьте добавление спецификатора типа

const short *p;
const volatile short *q;
void foo (void){
  q = ( const volatile short * ) p;  /* Compliant */								
}

В этом примере, обоих p и q может указать на short объекты. Бросок между ними добавляет volatile спецификатор только и поэтому совместим.

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

Группа: правило 03. Выражения (EXP)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.