i've searched a solution to solve the issue of controlling data type for while , and i thought that maybe my founding could add up well with the initial demand @con-f-use, even if it's no exactly the same issue.
An other way around to control the datatype could be done using an union with predefined type. In my case, i had a defined structure in which i was originally using a void* to allow divers data type to be passed :
originally:
//[main]:
uint32_t vtest3= 100000;
int32_t vtest2= 100000;
struct entity list[] = {
{ TYPE_INT32, s_int32_t, .label="tension", &vtest3},
{ TYPE_INT32, s_int32_t, .label="tension", &vtest3}
};
//[file.h]:
struct entity {
enum entity_type type;
uint32_t dimension;
char* label;
void* ptr_data;
uint32_t offset;
};
enum entity_type {
TYPE_NONE = 0,
TYPE_INT8 = 1,
TYPE_INT16 = 2,
TYPE_INT32 = 3,
TYPE_INT64 = 4,
TYPE_UINT8 = 5,
TYPE_UINT16 = 6,
TYPE_UINT32 = 7,
TYPE_UINT64 = 8,
TYPE_FLOAT32 = 9
};
The issue with this method is that it accept all type of variable in an uncontrolled way. There is no easy method to control the data type referenced by the void* pointer, Excepted maybe thought the use of a macro and _Generic as described before in this thread.
If the programmer decided to pass a type different from the list of type accepted ,there while be no error thrown at compile time.
. They other way around is by replacing the void* by an union , this way the structure while only accept specific data type defined inside the union list . If the programmer decide to pass a pointer with an type which is not already defined inside the ptr_data union{...} , it will throw an error.
//[file.h]:
enum entity_type {
TYPE_NONE = 0,
TYPE_INT8 = 1,
TYPE_INT16 = 2,
TYPE_INT32 = 3,
TYPE_INT64 = 4,
TYPE_UINT8 = 5,
TYPE_UINT16 = 6,
TYPE_UINT32 = 7,
TYPE_UINT64 = 8,
TYPE_FLOAT32 = 9
};
struct entity {
enum entity_type type;
uint32_t dimension;
char* label;
union {
uint8_t *uint8;
uint16_t *uint16;
uint32_t *uint32;
uint32_t *uint;
int16_t *int16;
int32_t *int32;
int64_t *int64;
float *f;
} ptr_data;
uint32_t offset;
};
[main:]
uint32_t vtest3= 100000;
int32_t vtest2= 100000;
struct entity list[] = {
{ TYPE_INT32, s_int32_t, .label="a", .ptr_data = {.uint16=&vtest1}
},
{ TYPE_INT32, s_int32_t, .label="b", .ptr_data = {.int32=&vtest2}
};
This method make use of the union to control implicitly the data type of the variable inserted by the programmer in the structure. If not correct the compiler while throw an error at compile time.
Obviously this code example is far from perfect and cannot be used directly but i tried to explain in a way as clear as possible the logic and the the idea that i proposed ;)