0

Consider the following type in C11, where MyType1 and MyType2 are previously declared types:

typedef struct {
  int tag;
  union {
    MyType1 type1;
    MyType2 type2;
  }
} MyStruct;

I'd like to allocate enough memory using malloc to hold the tag attribute and type1. Can this be done in a portable way? I guess, sizeof(tag) + sizeof(type1) may not work due to alignment issues.

Can I calculate the offset of type1 from the beginning of the structure in a portable way?

timrau
  • 22,578
  • 4
  • 51
  • 64
Marc
  • 4,327
  • 4
  • 30
  • 46
  • 1
    If you need `struct { int tag; MyType1 type1; }` why don't you explicitly define it? It's unclear what you need this, for but it smells like something that will probably break strict aliasing rule. – user694733 Jan 16 '15 at 10:20
  • @user694733: I want to use pointers to MyStruct. Depending on the tag field, I need type1 or type2. – Marc Jan 16 '15 at 10:57

2 Answers2

3

You can use offsetof(), and since that will include both the size of tag and any padding, it's enough to then add the size of type1:

void *mys = malloc(offsetof(MyStruct, type1) + sizeof (MyType1));
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
unwind
  • 391,730
  • 64
  • 469
  • 606
1

Can I calculate the offset of type1 from the beginning of the structure in a portable way?

You can probably use offsetof from stddef.h for this.

printf("Offset of type1 in the struct: %zu\n", offsetof(MyStruct, type1));

Side note: this works because you are using an "anonymous union". If you were to say union { ... } u; type1 wouldn't be a member of MyStruct.

cnicutar
  • 178,505
  • 25
  • 365
  • 392