Can a C++ compiler (specifically g++) re-order the internal elements of a struct?
I'm seeing some strange behaviour where I have a structure that contains something like the following:
Struct SomeStruct{
...
...
long someLong;
long someLongArray[25];
unsigned long someUnsignedLong;
unsigned long someUnsignedLongArray[8];
unsigned long int someUnsignedLongInt;
...
...
};
When I write output this to file, the order of someUnsignedLongArray and someLongArray seem to be reversed (i.e. the elements in someLongArray[] appear after someUnsignedLong and the elements of someUnsignedLongArray[] appear after someLong). Is this possible??
Thanks
Update: As requested, I am writing out the structure using the following:
int fd = open(fspec,O_RDWR|O_CREAT|O_TRUNC,0666);
int writeRes = write(fd,(char *)&someStruct,sizeof(SomeStruct));
For completeness, here is the full struct:
struct SomeStruct{
byte someByte;
byte someByteArray[6];
char someChar;
char someCharArray[5];
char someCharArrayArray[3][5];
short someShort;
signed short someShortArray[2];
unsigned short someUnsignedShort;
unsigned short someUnsignedShortArray[8];
int someInt;
int someIntArray[3];
int someIntArrayArrayArrayArray[4][3][2][6];
int *pSomeInt;
unsigned int someUnsignedInt;
unsigned int someUnsignedIntArray[9];
long someLong;
long someLongArray[25];
unsigned long someUnsignedLong;
unsigned long someUnsignedLongArray[8];
unsigned long int someUnsignedLongInt;
long long someLongLong;
long long someLongLongArray[5];
bool someBool;
bool someBoolArray[3];
unsigned long long someUnsignedLongLong;
unsigned long long someUnsignedLongLongArray[5];
unsigned long long someUnsignedLongLongArrayArray[5][2];
unsigned long long int *pSomeUnsignedLongLongInt;
};
A Standard C compiler won't rearrange the members of a structure automatically to reduce the structure's size.
The order of fields in a struct does matter - the compiler is not allowed to reorder fields, so the size of the struct may change as the result of adding some padding.
structs are not compiled, they are declared.
In C/C++, we can assign a struct (or class in C++ only) variable to another variable of same type. When we assign a struct variable to another, all members of the variable are copied to the other struct variable.
It normally can't reorder elements, no.
An exception is if there's an access specifier separating them:
struct Foo {
A a;
B b;
C c;
private:
D d;
E e;
F f;
};
a
, b
and c
are guaranteed to be stored in this order, and d
, e
and f
are guaranteed to be stored in order. But there is no guarantees about where a
, b
and c
are stored relative to d
, e
and f
.
Another thing to keep in mind is that the compiler can insert as much padding as it likes, even if it doesn't reorder anything.
Here's the relevant part of the standard:
Section 9.2.12:
Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1)"
It can't, see Automated field re-ordering in C structs to avoid padding and Why doesn't GCC optimize structs? for further information.
I don't know what you mean with "reversed", perhaps you should add some code and the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With