ПроблемаПроблема возникает, когда приведение выполняется между указателем на тип объекта и указателем на другой тип объекта.
РискЕсли указатель на объект приведен в указатель на другой объект, полученный указатель может быть неправильно выровнен. Неправильное выравнивание приводит к неопределенному поведению.
Даже если преобразование создает указатель, который правильно выровнен, поведение может быть неопределенным, если указатель используется для доступа к объекту.
Исключение: Вы можете преобразовать указатель в тип объекта в указатель на один из следующих типов:
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
только квалификатор и, следовательно, совместим.