Reputation: 573
I would like to know if it is possible to get the type to which I would like to cast dynamically. For eg.
void *ptr;
typedef struct {
..
common_field;
..
} some;
typedef struct {
..
common_field;
..
} some_other;
Now I want to know if I can typecast ptr
to type some or some_other dynamically.
precisely what I want to know is if it is possible to have a macro, TYPE_CAST(comdition)
which gives me the type like shown below:
(TYPE_CAST(condition)) ptr->common_field
should be equivalent to
((some *) ptr)->common_field or ((some_other *) ptr)->common_field
based on the condition
The following doesn't work, just giving this so that it might be clear to understand c than english:
TYPE_CAST(condition) ((condition) ? (some *) : (some_other *))
Can something along these lines can be done.
Thanks.
Upvotes: 1
Views: 192
Reputation: 6717
C90 does not support this directly
I assume you want to write a generic list of some sort in c90. Here are some snippets i use in a generic c90 list of mine:
typedef struct {
void *rigth;
void *left;
void *value;
int index;
}GENLIST_node;
#define GENLIST_getValuePtr(NODE, index, valptr) __GENLIST_getValuePtr ((NODE), (index), (void*)(valptr))
using this you can access the content when calling it and always get the rigth type back. Here are some examples:
int *NODEVALA = NULL;
double *NODEVALB = NULL;
char *NODEVALC = NULL;
GENLIST_getValuePtr(&AnyNode, -1, &NODEVALA);
GENLIST_getValuePtr(&AnyNode, -1, &NODEVALB);
GENLIST_getValuePtr(&AnyNode, -1, &NODEVALC);
there are obviousely some parts missing , but what i want to point out is that NODEVALA, NODEVALB and NODEVALC have whatever type you want them to have and the list saves them in form of a void pointer.
in your case this could be done with recursive calls during runtime
switch(condition){
case condition_structA:
structA *X;
getValPtr(&X);
...
break;
structB *X;
getValPtr(&X);
...
case condition_structB:
break;
}
In C90 there is no way the compiler can be used to do things like that automatically. To do this you would need polymorphism and that would be C++ or better.
Upvotes: 0
Reputation: 67489
A way to design your data structures to avoid your problem could be:
typedef struct {
int common_field;
union {
struct {
int member1;
} some;
struct {
char* member2;
} some_other;
};
} common_struct;
common_struct* ptr;
Then you can easily access the common member with ptr->common_field
regardless of which of the two variants you have. I would imagine that the value of this common field will tell you which of the two members of the union you need to use to access the remaining members, which you will then access as ptr->some.member1
or ptr->some_other.member2
.
Upvotes: 1
Reputation: 263267
That's pretty much not possible. The type of an expression is determined at compile time; it can't depend on any execution time condition.
You can, given a void*
that you know points to an object of one type or the other, do something similar (I have not tested this):
condition ? ((some*)ptr)->common_field : ((some_other*)ptr)->common_field
Note that the ->common_field
part of the expression has to be repeated; the compiler has to know the type of the left operand of the ->
operator.
(Depending on the context, an if/else statement might be clearer.)
Upvotes: 2