Started by trying to write a small program to translate basic arithmetic into English, I end up building a binary tree(which is inevitably very unbalanced) to represent the
You can't access members through void *
pointers. There are ways you could cast it (indeed, you don't even need to state the case explicitly with void *
), but even that is the wrong answer.
The correct answer is to use union
:
typedef union {
struct{
unsigned char entity_flag; /*positive when the oprd
struct represents an entity
---a single digit or a parenthesized block*/
char oprt;
expr * l_oprd;// these two point to the children nodes
expr * r_oprd;
} expr;
struct{
unsigned char entity_flag;
int ival;
} digit;
} expr;
You then access an expression like this (given a variable expr *e
):
e->expr->entity_flag;
And a digit like this:
e->digit->entity_flag;
Any other solution is a nasty hack, IMO, and most of the casting solutions will risk breaking the "strict aliasing" rules that say that the compiler is allowed to assume that two pointers of different types can't reference the same memory.
Edit ...
If you need to be able to inspect the data itself in order to figure out which member of the union is in use, you can.
Basically, If the top-most fields in two structs are declared the same then they will have the same binary representation. This isn't just limited to unions, this is true in general across all binaries compiled for that architecture (if you think about it, this is essential for libraries to work).
In unions it is common to pull those out into a separate struct so that it's obvious what you're doing, although it's not required:
union {
struct {
int ID;
} base;
struct {
int ID;
char *data
} A;
struct {
int ID;
int *numeric_data;
} B;
}
In this scheme, p->base.ID
, p->A.ID
, p->B.ID
are guaranteed to read the same.