У меня есть модуль, реализацию которого я хочу скрыть от своих клиентов.
Я решил объявить непрозрачный тип, который фактически является указателем на структуру, которая должна быть определена только в реализации.
Все работает нормально, за исключением того, что я могу присвоить нулевое значение переменной этого типа, чего я хочу избежать.
Вот пример на 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!! */
}
Непрозрачный тип на самом деле является указателем на динамически размещенную структуру;
Если я присваиваю ему значение 0, я получаю утечку памяти, которой можно избежать, если компилятор отклонит присвоение 0 этому непрозрачному указателю.
Присвоение ненулевых значений указателю не принимается компилятором, поэтому я полагаю, что с немного большими усилиями этого можно было бы достичь для нулевого значения.
Можно ли отключить это назначение? Как я могу этого достичь?
Если потребуется использование некоторых конструкций, специфичных для C ++ или gcc, я согласен с этим, хотя было бы неплохо чисто C-решение.
Заранее спасибо.