Приведение целочисленной константы к типу указателя - PullRequest
3 голосов
/ 19 апреля 2019

Является ли UB приводить произвольную целочисленную константу к указателю на тип объекта / функции (например, для использования в модульных тестах)?

struct helper; //opqaue, creation the structure is complicated

struct my_struct{
   struct helper *h_ptr;
   char another_member;
};

static inline struct my_struct *create_my_struct(struct helper *h_ptr, char am){
    struct my_struct *m_ptr = malloc(sizeof(*m_ptr));
    m_ptr->h_ptr = h_ptr;
    m_ptr->another_member = am;
    return m_ptr;
}

Я хочу написать для нее модульный тест следующим образом:

uintptr_t helper_ptr = (uintptr_t) 2; //How about this?
char am = 'a';
struct my_struct *ms_ptr = create_my_struct((struct helper *) helper_ptr, am);
//do asserts

В чем я не уверен, так это (struct helper *) helper_ptr.Это UB?Что если (uintptr_t) 2 выровнен неправильно?

Ответы [ 3 ]

4 голосов
/ 19 апреля 2019

Из стандарта C11 6.3.2.3 Указатели, параграф 5:

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

Таким образом, вы можете делать это до тех пор, пока вы не разыменуете его, и это не UB, но то, что произойдет, будет зависеть от платформы.

3 голосов
/ 19 апреля 2019

Я считаю, что он определен (если вы не разыменовываете), даже если указатель не выровнен правильно.

6.3.2.3p5 Упоминает возможность неправильного выравнивания для intПреобразование -to-ptr без видимого прикрепления к нему неопределенного поведения:

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

Напротив, 6.3.2.3p6 говорит, что преобразования указатель-указатель преобразования, которые приводят к неверно выровненному указателю , являются неопределенным поведением.(Неформальное приложение J.2 , в котором перечислены неопределенные варианты поведения, также перечисляет только смещение указателя, возникающее из преобразований указатель-указатель как UB).

(Это было бы интересноподразумевает, что любое преобразование указателя в указатель может быть упрощено без UB, если использовать в качестве посредника целое число достаточного размера (если оно существует).)

0 голосов
/ 19 апреля 2019

Реле программирования целевого уровня памяти, записанное на нем, на нем.

например:

#define GPIO_Typedef *GPIOA (voaltile GPIO_Typdef *)0x40000300

и тогда мы можем разыменовать его, обращаясь к регистру в памяти

 GPIOA -> MODER = .....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...