什么时候使用C中的指针指针来输入双关语是合法的?

Adr*_*ala 6 c pointers type-conversion

在C程序中,我有一个结构

typedef struct {
    void *payload; // opaque, real type known to callbacks

         ... some stuff ...
} MiddleMan;
Run Code Online (Sandbox Code Playgroud)

为了创建一些类型安全的贴面,我可能会创建getter和setter

CbData *get_cb_data(const MiddleMan *mm){ return mm->payload; }   
void set_cb_data(MiddleMan *mm, CbData *cbd){ mm->payload = cbd; }
Run Code Online (Sandbox Code Playgroud)

或者我可以尝试用一个基于指针的访问器来完成它

CbData **cb_data(MiddleMan *mm){return (CbData**)&mm->payload;}
Run Code Online (Sandbox Code Playgroud)

现在第二个解决方案看起来比第一个解决方案更加笨拙,并且它还将用户限制为非const mm即使他们只想阅读.但我的问题是它是否合法C?

我相当肯定你可以在任何void*大小和格式相同的架构上逃脱它CbData*.但是,任何人都可以明确推断为什么这一般(或不是)有效吗?

Eri*_*c Z 4

一般来说,你不应该这样做。Avoid**可能与 具有不同的对齐要求CbData**。显式强制转换可能会产生不同的地址。

C 标准 6.2.5.27:

指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。39) 类似地,指向兼容类型的限定或非限定版本的指针应具有相同的表示和对齐要求。所有指向结构类型的指针应具有相同的表示和对齐要求。所有指向联合类型的指针应具有相同的表示和对齐要求。指向其他类型的指针不需要具有相同的表示或对齐要求。