Ani*_*lM3 11 c struct pthreads unions
我正在读取pthreads库的头文件,并在bits/pthreadtypes.h中找到了互斥体(和其他类型)的这个特定定义:
typedef union
{
struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
int __owner;
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
unsigned int __nusers;
__extension__ union
{
int __spins;
__pthread_slist_t __list;
};
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
} pthread_mutex_t;
Run Code Online (Sandbox Code Playgroud)
它不完全是这样,但为了清晰起见我简化了它.在头文件和实现文件中创建一个具有两个不同定义的结构,实现真正的结构定义,标题只是真实结构大小的字符缓冲区,用作隐藏实现的技术(opaque类型) )但在调用malloc或在堆栈中分配对象时仍然分配正确的内存量.
这个特殊的实现使用了一个union并且仍然暴露了struct的结构和字符缓冲区,但是在隐藏类型方面似乎没有提供任何好处,因为结构仍然暴露,并且二进制兼容性依赖于结构没有变化.
我的看法是,__size和__align字段指定(猜:-))的结构的大小和对齐独立的__data结构.因此,数据可以是更小的尺寸并且具有更少的对准要求,它可以自由地修改而不会破坏关于它的这些基本假设.反之亦然,这些基本特征可以在不改变数据结构的情况下进行更改,就像这里一样.
重要的是要注意,如果大小__data超过指定的大小,则__SIZEOF_PTHREAD_MUTEX_T断言失败__pthread_mutex_init():
assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T);
Run Code Online (Sandbox Code Playgroud)
将此断言视为此方法的重要组成部分.
因此,结论是这样做不是为了隐藏实现细节,而是为了使数据结构更具可预测性和可管理性.对于一个广泛使用的库来说非常重要,它应该关注可以对这个结构进行的更改中的后向兼容性和对其他代码的性能影响.