Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of fields in C/C++ structs

I have a situation similar to this one

struct Child
{
  u16 x, y;
  // other fields
};

struct Father
{
  struct Child child1;
  struct Child child2;
  // other fields
};

Father tilemap[WIDTH][HEIGHT];

Now I just realized I would like to save four bytes for x,y which are set always to the same values for both children of the same father.

All around my code I pass around many Father* and many Child* while recovering coordinates with father->child1->x or child1->x respectively. I would like to safely move the coordinates at Father level but I'm unsure about some facts.

Will the order of declared fields be respected versus any optimization or possible implementation of gcc/g++? Can I be confident that &father == &father.child1?

The real issue here is that I pass Child* without knowing if it's a child1 or child2 field so I cannot directly know the offset to recover address of father (and coordinates consequently).. I was wondering to use a bit at Child level to distinguish them but will I be easily able to recover address of father then?

Any suggestion would be appreciated, thanks

EDIT: just as a further info, I'm using C++ as my main language but these structs don't contain ANY strange methods, just fields and empty constructor.

like image 607
Jack Avatar asked Jan 26 '26 12:01

Jack


2 Answers

The general rules about field layout in C are:

  1. The address of the first member is the same as the address of the struct itself. That is, the offsetof of the member field is 0.
  2. The addresses of the members always increase in declaration order. That is, the offsetof of the n-th field is lower than that of the (n+1)-th member.

In C++, of course, that is only true if it is a standard layout type, that is roughly, a class or struct with no public/private/protected mixed members, no virtual functions and no members inherited from other classes.

like image 76
rodrigo Avatar answered Jan 29 '26 01:01

rodrigo


Disclaimer: Partial answer. C++ only

Will the order of declared fields be respected versus any optimization or possible implementation of gcc/g++?

The order of the members in the memory layout will not be tampered with by the compiler. It's the same order you declared the members in.

Can I be confident that &father == &father.child1?

In this particular case, yes. But it does not follow from the mere fact that child1 is the first member of father that &father == &father.child1?. This is true only if father is a POD, which in this case it is.

like image 42
Armen Tsirunyan Avatar answered Jan 29 '26 03:01

Armen Tsirunyan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!