I am trying to declare a generic variable type in C (I can't us C++), and I have in my mind the following options.
Option1
typedef struct
{
void *value;
ElementType_e type;
} Data_t;
Option 2
typedef struct {
ElementType_e type;
union {
int a;
float b;
char c;
} my_union;
} my_struct;
where ElementType_e is an enum that holds all the possible type of variables (e.g. int, char, unsigned int, etc..). I am kinda leaning toward option 1, because I don't believe casting will add extra computational time, compared to switch, right?
I am just wondering which type is more useful? I know option 1 will require casting every-time being used/accessed. is there any possible issues that could happen with casting ( especially with running/compiling the code on different platform, e.g 32 bits and 16 bits micro)
While option2 require a switch () to do any operation (e.g. addition, ...).
The following link explained that Option 2 is better ( from readability point of view), but i mainly concern about the code size and computational cost. Generic data type in C [ void * ]
is there any possible issues that could happen with casting
No, as you do not want cast, as there is no need to cast when assigning from/to a void-pointer (in C).
I am just wondering which type is more useful?
Both do, so it depends, as
ElementType_e).Referring a comment:
Regarding performance I expect no major difference between both approaches (if implemented sanely), as both options need condtional statments on assigning to/from (exception here are pointer variables, which for option 1 go without conditonal statements for assignment).
I'd recommend using a union. In fact, I've used one myself in a similar situation:
union sockaddr_u {
struct sockaddr_storage ss;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
I use this union in socket code where I could be working with either IPv4 or IPv6 addresses. In this particular case, the "type" field is actually the first field in each of the inner structs (ss.ss_family, sin.sin_family, and sin6.sin6_family).
I think the problem is not well posed, since there are infinite possible data types definable by the programmer. Consider for example the following sequence:
typedef char S0_t;
typedef struct { S0_t x; } S1_t;
typedef struct { S1_t x; } S2_t;
typedef struct { S2_t x; } S3_t;
It's pretty clear that it's possible to follow indefinitely in order to define as many new types as we want.
So, there is not a straight manner to handle this possibilities.
On the other hand, as pointers are of more flexible nature, you can take the decision of defining a generic type concerned only with pointer types.
Thus, the types used in your project will have to be only pointers.
In this way, probably something very simple like the following definition could work:
typedef void* generic_t;