Правило 11.3 MISRA C:2012

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

Описание

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

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

Объяснение

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

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

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

  • 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 только и поэтому совместим.

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

Группа: преобразования типа указателя
Категория: необходимый
Категория AGC: необходимый
Язык: C90, C99

Введенный в R2014b