ПроблемаПроблема возникает, когда выполняется преобразование между указателем на объект и целым типом.
Смещения или неявные преобразования из NULL
или (void*)0
не генерируйте предупреждение.
РискПреобразование между целыми числами и указателями может вызвать ошибки или неопределенное поведение.
Если целое число приведено к указателю, полученный указатель может быть неправильно выровнен. Неправильное выравнивание приводит к неопределенному поведению.
Если указатель приведен к целому числу, полученное значение может оказаться вне допустимой области значений для целого типа.
Пример - Смещения между указателем и целым числом#include <stdbool.h>
typedef unsigned char uint8_t;
typedef char char_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef _Bool bool_t;
uint8_t *PORTA = (uint8_t *) 0x0002; /* Non-compliant */
void foo(void) {
char_t c = 1;
char_t *pc = &c; /* Compliant */
uint16_t ui16 = 7U;
uint16_t *pui16 = &ui16; /* Compliant */
pui16 = (uint16_t *) ui16; /* Non-compliant */
uint16_t *p;
int32_t addr = (int32_t) p; /* Non-compliant */
bool_t b = (bool_t) p; /* Non-compliant */
enum etag { A, B } e = ( enum etag ) p; /* Non-compliant */
}
В этом примере правило нарушается, когда:
Целое число 0x0002
приведен к указателю.
Если целое число определяет абсолютный адрес, то чаще всего назначают адрес указателю в заголовочном файле. Чтобы избежать маркировки назначения, можно исключить файлы заголовков из проверки правил кодирования. Для получения дополнительной информации смотрите Do not generate results for (-do-not-generate-results-for)
.
Указатель p
приведен к целым типам, таким как int32_t
, bool_t
или enum etag
.
Правило не нарушается, когда адрес &ui16
назначается указателю.