如何在不使用 Malloc 的情况下使 typedef 尽可能私有?

How to make a typedef as private as possible without using Malloc?

我正在寻找一种方法来制作只能从一组特定的函数调用(setBit(bit_typ *const t),getBit(bit_typ *常量 t))。我正在寻找一种不使用 malloc 的方法来做到这一点,有人有什么想法吗?

EDIT:// 这个问题与 this one 不同,因为它正在寻找接近 "private" 结构的方法,而另一个问题(TL;DR 有办法定义一个不透明类型,它仍然可以在堆栈上分配,并且不会违反严格的别名规则?)寻找与我的问题的一种可能解决方案相关的问题的解决方案。

一种方法是公开不透明类型的总 大小 并使用将不透明类型的对象声明为 unsigned char [N] 缓冲区。例如,假设您有一些类型 OpaqueType,您希望向用户隐藏其内部结构。

在头文件中(暴露给用户)你这样做

typedef unsigned char OpaqueType[16];

其中 16 是您要隐藏的类型的确切字节大小。在头文件中,您根据该类型编写整个接口,例如

void set_data(OpaqueType *dst, int data);

在实现文件中声明实际类型

typedef struct OpaqueTypeImpl
{
  int data1;
  double data2;
} OpaqueTypeImpl;

实现功能如下

void set_data(OpaqueType *dst, int data)
{
  OpaqueTypeImpl *actual_dst = (OpaqueTypeImpl *) dst;
  actual_dst->data1 = data;
}

您还可以添加静态断言,以确保 sizeof(OpaqueType)sizeof(OpaqueTypeImpl) 相同。

当然,正如下面的评论中所指出的,必须采取额外的步骤来确保此类对象的正确对齐,例如 C11 中的 _Alignas 或 [= 中的一些基于联合的技术46=] C.

这样你就给了用户声明 OpaqueType 的非动态对象的机会,即你不会强迫用户调用你的函数,在内部 malloc 这样的对象。同时,您不会向用户公开您类型的内部结构的任何信息(除了其总大小和对齐要求)。

另请注意,以这种方式声明的 OpaqueType 是一个数组,这意味着它不可复制(除非您使用 memcpy)。如果您想主动防止不受限制的用户级复制,那可能是一件好事。但是如果你想启用复制,你可以将数组包装成一个结构。

这种方法不是非常优雅,但是当您希望让您的类型的对象自由由用户定义时,这可能是隐藏实现的唯一方法。