There is no way to do such a thing in C! Except by using a void*, which is not an efficient/safe way.
Why do you believe that using a (void*) is not an efficient/safe way?
If you want to hide implementation details in C, it is a common technique to expose it as typedef to (void*)
in a header and provide functions to manipulate it.
Here is an exaple header for a dynamic type holding integers and strings:
/* Dynamic types in C */
#define DYNAMIC_INT 0
#define DYNAMIC_STRING 1
struct dynamic_phantom;
typedef struct dynamic_phantom* dynamic;
dynamic dynamic_of_int(int c);
dynamic dynamic_of_string(char *s);
int dynamic_classify(dynamic v);
int dynamic_get_int(dynamic v, int *c);
int dynanic_get_string(dynamic v, char **s);
void dynamic_free(dynamic v);
I hope that the names of the functions and their protoypes are enough to get what they are for. There is a lot of options to implement this. Let me outline two popular choices:
UNIONS
In your implementation file, you implement the dynamic
as a union
like this:
union dynamic_value {
int value_int;
char* value_string;
};
struct dynamic_cell {
int cell_type;
union dynamic_value cell_value;
};
typedef struct dynamic_cell *dynamic;
and implement the functions I enumerated above is straightforward. (Of course, you can refine this in several ways, defining error control procedures, add control bits if you wish to avoid duplicating string contents, and so on.)
SPECIALISED MEMORY POOLS
For each available dynamic type, you allocate a memory pool, i.e. a large array of such values. A dynamic value is then implemented as a pointer to some value in these memory pools casted to void*
. The type of the value is then recovered from the pointer range.
An advantage of this strategy over the previous one is that it natively deals with values of different sizes while the union approach takes the biggest size of the possible value types. It is however slightly more complicated to implement, especially because of memory management—it needs to reimplement efficiently the logic of malloc
if you want to deal with a significant number of values.