我有一个模块,我想对其客户隐藏其实现。
我选择声明一个不透明类型,它实际上是一个指向仅在实现中定义的结构的指针。
一切正常,除了我可以将零值分配给这种类型的变量,我想避免这种情况。
这是 C 中的一个示例。
头文件 foo.h
/* foo.h */
typedef struct foo *foo_t; /* <- sorry this was obviously flawed, the '*' was missing */
extern void foo_create( foo_t *t );
extern void foo_destroy( foo_t *t );
extern void foo_tile( foo_t x );
实现文件 foo.c
/* foo.c */
#include <stdlib.h>
#include "foo.h"
struct foo {
int some_member;
};
void foo_create( foo_t *t )
{
if ( *t==0 ) {
*t = malloc( sizeof(struct foo) );
}
}
void foo_destroy( foo_t *t )
{
if ( *t!=0 ) {
free(*t);
*t = 0;
}
}
void foo_tile( foo_t t )
{
t->some_member++;
}
现在这是一个使用模块的示例客户端:bar.c:
#include "foo.h"
int main( int argc , char **argv )
{
foo_t toe;
foo_create( &toe );
toe = 0; /* <-- How to make the compiler (gcc) refuse this? */
toe = 1; /* <--- the compiler rejects this YAY!! */
}
opaque 类型实际上是一个指向动态分配结构的指针;如果我将值 0 分配给它,我会发生内存泄漏,如果编译器拒绝将 0 分配给此不透明指针,则可以避免这种情况。
编译器不接受为指针分配非空值,因此我认为通过更多的努力可以实现零值。
是否可以禁用此分配?我怎样才能做到这一点?如果需要使用一些 C++ 或 gcc 特定的构造,我会同意的,尽管纯 C 解决方案会很好。
提前致谢。