0

Can I do something like this? I would like to use data types instead of constants in my enum type_t.

typedef struct {
    char id;
    long data;
} type1_t;

typedef struct {
    char id;
    long data;
    float moredata;
} type2_t;

typedef enum {
    type1_t, type2_t
} type_t;

typedef struct {
    type_t type;
    char* something;
} midas;

midas obj1;
obj1.type = type1_t;
obj1.type.id = 0;
obj1.type.data = 123;

midas obj2;
obj2.type = type2_t;
obj2.type.id = 3;
obj2.type.data = 456;
obj2.type.moredata = 3.14;

In the example the type variable of the midas struct should then refer to type1_t or type2_t. So if I set the type to type2_t, the size of it should be bigger than when I set type1_t.

5 Answers 5

2

No, you can't do that. If you were using C++, you could use templates to achieve this. But there is no "type enum" mechanism in C.

You could consider a union:

typedef enum {
    type1, type2
} type_t;

typedef struct {
    type_t typecode;
    union {
        type1_t type1value;
        type2_t type2value;
    };
    char* something;
} midas;

This will cause midas.type1value and midas.type2value to occupy the same memory space. The amount of memory taken for the union will be equal to the amount of memory required to store the largest data type it contains.

You would then have to look at midas.typecode and consider which union member to use. If you use the wrong one you will wind up with invalid data and this may lead to program crashes, so be careful.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that was a quick response! Isn't there a way to allocate memory for the union, or isn't that needed?
The memory is allocated as part of the midas struct itself. The regions of memory used will just overlap, so you should only ever use one or the other for any given instance of the struct. You can demonstrate this by asserting: midas value; if (&(value.type1value) == &(value.type2value)) printf("The members are in a union.\n"); You will see that pointers to each member of the union are equal in value.
2

No. The usual way to do something like this in C is with a union:

typedef enum { TYPE1, TYPE2 } type_t;

typedef struct {
    type_t type;
    union
    {
        type1_1 t1;
        type2_t t2;
    } u;
} midas;

midas obj1;
obj1.type = TYPE1;
obj1.u.t1.id = 0;
obj1.u.t1.data = 123;

midas obj2;
obj2.type = TYPE2;
obj2.u.t2.id = 3;
obj2.u.t2.data = 456;
obj2.u.t2.moredata = 31.14;

2 Comments

The union can be anonymous to avoid the u. everywhere. Before that was widely supported it was common to have blocks of #define t1_id u.t1.id
@Ben Jackson: That's true, but that's not standard C, it's an extension to C provided by compilers. If you want completely portable code, you should not use anonymous unions.
1

I think you are looking for union

Comments

1

No, you can't do that. enums are more or less equivalent to ints.

You can do this sort of thing was a union, e.g.:

typedef struct
{
    int   a;
    float b;
} type1_t;

typedef struct
{
    char  c;
    long  d;
} type2_t;

typedef union
{
    type1_t  t1;
    type2_t  t2;
} myUnion_t;


...

myUnion_t u;
u.t1.a = 3;
u.t1.b = 2.7f;

Comments

0

That does not work. The closest thing would be to use a void* to your structure.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.