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
未正确对齐怎么办?
答案 0 :(得分:4)
根据C11标准6.3.2.3指针的第5段:
整数可以转换为任何指针类型。除非先前指定,否则结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,并且可能是陷阱表示。
因此只要不取消引用它就可以做到这一点,而且它不是UB,但是发生什么情况取决于平台。
答案 1 :(得分:3)
我相信即使指针未正确对齐,它也是已定义的(如果您不取消引用)。
6.3.2.3p5 提到从int到ptr转换的对齐方式可能不正确,而似乎没有附加未定义的行为:
整数可以转换为任何指针类型。除了以前 指定,结果是实现定义的,可能不是 正确对齐,可能未指向所引用的实体 类型,并且可能是陷阱表示。
相反,6.3.2.3p6说,指针到指针转换导致未对齐的指针 是不确定的行为。 (非正式的J.2附录列出了未定义的行为,也仅列出了由于 pointer-to-pointer 转换为UB而引起的指针未对齐)。
(有趣的是,这可以通过使用足够大的整数(如果存在)来促进任何指针到指针的转换而无需UB)。
答案 2 :(得分:0)
整个存储器映射寄存器的硬件级编程在其上进行中继。
例如:
#define GPIO_Typedef *GPIOA (voaltile GPIO_Typdef *)0x40000300
然后我们可以取消引用它以访问内存中的寄存器
GPIOA -> MODER = .....