提问人:Mark 提问时间:1/11/2019 更新时间:1/11/2019 访问量:1396
从不兼容的指针类型分配:强制类型?
assignment from incompatible pointer type: forcing the type?
问:
struct my_struct {
int p;
uint32_t *a;
...
};
struct my_struct *aa;
...
struct b {
uint8_t b;
...
};
struct b *bb;
此时,已初始化,包含有效值。bb
aa
bb
aa->a = &bb->b;
但是,这会导致编译器警告,这是有道理的:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
执行以下操作是否安全?
aa->a = (uint32_t *)&bb->b;
答:
2赞
John Bollinger
1/11/2019
#1
执行以下操作是否安全?
aa->a = (uint32_t *)&bb->b;
C 允许您在不同的对象指针类型之间进行转换。将表达式的值转换为 类型后,您当然可以将结果分配给 。从这个意义上说,这种说法本身是安全的。&bb->b
aa->a
aa->a
但事后取消引用是不安全的。这样做的结果是明确未定义的。据我推断,这就是你接下来打算做的事情,不,你的整体计划是不安全的。aa->a
如果需要一个可以指向 a 或 a 的指针,请使用 或 a 或 。在极有可能是 的别名的情况下,您还可以使用 .uint32_t
uint8_t
void *
char *
unsigned char *
uint8_t
unsigned char
uint8_t *
评论
2赞
chux - Reinstate Monica
1/11/2019
不同意这里对转换安全性的乐观看法。“C 允许您在不同的对象指针类型之间进行转换” Hmmm: “如果生成的指针未正确对齐引用的类型,则行为未定义。” 肯定不对齐,并且此代码有 UB 风险 - 无论是否在以后取消引用。OTOH,也许都有相同的对齐方式?bb->b
(uint32_t *)&bb->b
struct
2赞
John Bollinger
1/11/2019
@chux,这是一个很好的观察。实际上,有两个。当然,所有结构指针类型都具有相同的表示形式。如果我们吹毛求疵,那么我认为这实际上并不要求它们具有相同的对齐要求,但在实践中,我认为在将指向一个结构的第一个成员的指针转换为另一个结构的第一个成员的类型时,不存在任何合理的可能性。
评论
uint8_t*
uint32_t*
netlink
u8
a
uint32_t
union
void*
my_struct
netlink
recv()