在C程序中我有一个结构
typedef struct {
void *payload; // opaque, real type known to callbacks
... some stuff ...
} MiddleMan;
要创建一些类型安全的贴面,我可能会创建getter和setter
CbData *get_cb_data(const MiddleMan *mm){ return mm->payload; }
void set_cb_data(MiddleMan *mm, CbData *cbd){ mm->payload = cbd; }
或者我可以尝试使用一个基于指针的单一访问器
CbData **cb_data(MiddleMan *mm){return (CbData**)&mm->payload;}
现在第二个解决方案看起来比第一个解决方案更加笨拙,并且即使他们只想阅读,它也会将用户限制为非const mm
。但我的问题是它是否合法C?
我很确定你可以在任何void*
大小相同的架构上侥幸逃脱。格式为CbData*
。但是,任何人都可以明确推断为什么这一般(或不是)有效吗?
答案 0 :(得分:4)
一般来说,你不应该这样做。 void**
可能与CbData**
具有不同的对齐要求。显式转换可能会产生不同的地址。
C标准6.2.5.27:
指向void的指针应具有相同的表示和对齐方式 要求作为指向字符类型的指针.39)同样,指针 合格或不合格版本的兼容类型应具备 相同的表示和对齐要求。所有指针 结构类型应具有相同的表示和对齐方式 彼此的要求。所有指向union类型的指针都应该有 相同的表示和对齐要求。指针 其他类型不需要具有相同的表示或对齐 要求。