tags:

views:

294

answers:

4

hi,

I am porting our application from solaris sparc to solaris x86 and I encountered a size differences of struct between these two architecture. for example; I have a struct like

typedef struct mystructS
{
  double a;
  double b;
  double c;
  double d;
  double e;
  double f;
  double g;
  double h;
  double aa;
  double ab;
  double ac;
  double ad;
  double ae;
  double af
  double ag;
  double ah;
  int ba;
  int bb;
  int bc;
  char ca[256];
} mystructT;

When i write sizeof(mystructT) in solaris X86, it returns 396

When i write sizeof(mystructT) in solaris SPARC, it returns 400

I just curious, why something like this happens?

EDIT: both solaris systems are 32 bit.

+2  A: 

If the SPARC is 64 bit, the compiler might try to align ca on a boundary, meaning it would pad an extra 4 bytes between bc and ca. If that's the case, you can probably ask the compiler to pack the structure so it won't add the padding bytes, but how you tell it to do that tends to be a bit compiler-dependent.

Eric Warmenhoven
No, both solaris is 32 bit. but thx
Aykut
this makes little sense, chars never need to be aligned. Why would ca[0] be aligned, when ca[1] never will be?
roe
+4  A: 

For whatever reason (perhaps doubles need to be aligned on sparc and not on x86?) it appears it's trying to make sure the next struct is aligned on a 64 bit boundary.

That is, in order for you to jump sizeof(mystructT) steps in memory and still end up pointing to the beginning of your struct (for example, when creating an array of structs, this is what you'd be doing when iterating over it), the struct must be padded at the end.

roe
I can confirm that Sun CC aligns double on x86 to 4 bytes boundaries while it aligns them on Sparc to 8 bytes boundaries. FWIW, gcc on linux 86 aligns doubles to 8 bytes boundaries.
AProgrammer
+1 I should read existing answers more carefully before starting my own.
Pascal Cuoq
'offsetof(3)' from stddef.h could also prove useful here
joveha
A: 

Since structure member padding and alignment are always implementation defined, you should never make any assumptions about the sizof a struct (even between different versions of the same compiler on the same platform, or the same compiler with different optimisation settings).

If you need specific alignment and packing, you must use compiler specific directives to achieve this. This may be by command-line compilation option, #pragma directive or in GCC and some other compilers __attribute__ specifications. Or perhaps more robustly (but more work) use data serialisation.

Clifford
I don't argue that the standard doesn't guarantee anything. I have never seen optimization options discussed in the context of implementation-defined behaviors, though, and I would appreciate a reference if you have one. And pragmatically, we couldn't have ABIs if the situation was as dire as you are saying. There are struct definitions in the system headers of my standard library and they define the same layout for all optimization levels of the system C compiler.
Pascal Cuoq
@Pascal: You are probably right, it is not as bad as that; but different systems have different ABIs, but it will do no harm to write code as if it were. Even on x86, Linux and Windows ABIs differ between each other and between 32 and 64bit versions.
Clifford
A: 

Most likely, alignof(double) is 8 with one compiler and 4 with the other.

The alignment of a struct is compiled as the smallest common multiple of the alignments of its fields, and in this particular case, it means that the aligment of double decide of the alignment of struct mystructS.

The size of a struct has to be a multiple of its alignment (this is for things to work well if you ever make an array of such a struct). Therefore, the compiler on which the alignment of the struct is 8 has to round up the size to a multiple of 8, too, by adding padding at the end.

Pascal Cuoq