I've got some C code with various functions that each take a different type of "handle" object as an argument. The implementation of all of these handles is the same (it's just a struct with a void-pointer and an item-count), so it seems logical to just declare a single implementation -- but I also want the C compiler to generate a compile-time error when the user passes in a handle of the wrong type to a function.
My current approach uses typedef
to create the various handle-types, which works to document which handle-type a function should accept, but the compiler does auto-conversion and so it doesn't flag type-mismatches as errors. Is there a recommended way to implement this, that doesn't require manually duplicating my handle-struct-declaration for every type?
Toy example code follows:
typedef struct _FruitHandle {
int _numItems;
void * _items;
} FruitHandle;
typedef FruitHandle AppleHandle;
typedef FruitHandle BananaHandle;
// imagine a number of other fruits as well
void EatAnApple(AppleHandle a) {}
void EatABanana(BananaHandle b) {}
// and so on -- each function should ONLY except its own fruit-handle-type as an argument!
int main(int argc, char ** argv)
{
AppleHandle apple;
BananaHandle banana;
EatAnApple(apple); // ok -- types match
EatABanana(banana); // ok -- types match
EatAnApple(banana); // type mismatch -- I want this to be a compile-time error, but it isn't!
EatABanana(apple); // type mismatch -- I want this to be a compile-time error, but it isn't!
return 0;
}
You might find the answers to this question helpful. While there is no explicit type inheritance in C, you can use the idiom described in the top answer to create AppleHandle and BananaHandle.
typedef struct {
int _numItems;
void *_items;
} FruitHandle;
typedef struct {
FruitHandle fruit_handle;
} AppleHandle;
typedef struct {
FruitHandle fruit_handle;
} BananaHandle;
...