6

在 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;}

现在第二种解决方案看起来比第一种更狡猾,而且它也将用户限制为非常量,mm即使他们只想阅读。但我的问题是它是否甚至是合法的C?

我相当确定你可以在任何void*CbData*. 但是任何人都可以给出明确的理由,为什么这通常是(或不是)有效的?

4

1 回答 1

4

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

C标准6.2.5.27:

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

于 2013-09-05T13:25:59.250 回答