------- Comment #2 from bliss1940-bbs at yahoo dot com  2007-05-21 22:18 -------
(In reply to comment #1)

I don't think I said GCC was in error, but just different.

Maybe we can come to an agreement here, or maybe not.  Let's see.

I certainly would expect the ARM7 would prefer that 4 byte operands (ints, in
this case) would be on addresses that are a multiple of 4, 2 byte operands
(shorts) would want to be at addresses that are a multiple of two, and 1 byte
operands (chars) have no alignment requirement so could go anywhere.

I would expect to see that somewhere in the ABI.  I would also expect to see
that in the ABI for the Intel Pentium.  I would not expect to see anything in
the ABI concerning structs as the hardware knows nothing about them.  They are
the figment of the imagination of the compiler and programmer.

So I would expect the Microsoft compiler targeting the PC and the GNU compiler
targeting the ARM7 would align shorts and ints accordingly.  Indeed, that's
what I see when I examine the code.

By the way, there is a good explanation of this on Wikipedia:  It mentions that
compilers usually arrange structs so the primitive objects they contain are at
appropriate addresses.  It explains why it's more efficient for the hardware,
and it also explains how the GNU and Microsoft compilers do it when targeting
the PC.  So far, so good.
http://en.wikipedia.org/wiki/Data_structure_alignment

But the GNU compiler does something else.  It makes the size of all structs a
multiple of 4.  I can think of one reason to do this.  GNU compiled code can
copy any struct by accessing memory 4 bytes at a time.  That is, it can
consider every struct to be composed of ints, and they will all be aligned
correctly.  If this is a good enough reason to make all structs a multiple of
4, then so be it.  But it's confusing to mention the ABI, because the ABI has
nothing to do with such things.  And it's confusing to mention data alignment
because it's an artificial requirement due to the way GNU copies structs.  It
has nothing to do with the struct data members as seen by the programmer.

Here are some examples of structs compiled by Microsoft for the PC, and  also
compiled by GNU for the ARM7 (Analog Devices ADuC7024).  These are the only
compilers I currently have.

                                    Microsoft                  GNU
      struct Char1   {             sizeof() == 1        sizeof() == 4
         char char1;
         };

      struct Char2   {             sizeof() == 2        sizeof() == 4
         char char1;
         char char2;
         };

      struct Char3   {             sizeof() == 3        sizeof() == 4
         char char1;
         char char2;
         char char3;
         };

      struct Char4   {             sizeof() == 4        sizeof() == 4
         char char1;
         char char2;
         char char3;
         char char4;
         };

      struct Char5   {             sizeof() == 5        sizeof() == 8
         char char1;
         char char2;         
         char char3;
         char char4;
         char char5;
         };

Note that the above structs only have chars so by definition they are aligned
correctly.  But Microsoft's structs are only as large as necessary,  GNU's are
padded to a multiple of 4 bytes.  This has nothing to do with the alignment of
the data members as they have no particular alignment requirement.  But as
mentioned before, GNU can copy any struct accessing memory 4 bytes at a time. 
There is no other reason I can think of to pad these structs to a multiple of 4
bytes.



Here are some structs that contain shorts (2 byte) to show what data alignment
means to me, to the wiki, to the hardware, and I think also to most people.

                                    Microsoft                  GNU
   class Short1   {
      char char1;                  sizeof() == 4        sizeof() == 4
      short short1;
      };

   class Short2   {                sizeof() == 6        sizeof() == 8
      char char1;
      short short1;
      short short2;
      };

Here a hole is inserted after the char.  This is required to align the 2 byte
short on the appropriate address.  Both Microsoft and GNU agree, as do most
everyone.  This is an ABI issue.  But notice the second class, Short2.  I added
a second short which will automatically have the correct alignment because it
immediately follows another short.  It doesn't require padding to be aligned
correctly.  Everyone agrees on this.  But the Microsoft compiler gives the size
as 6.  As always, the GNU compiler adds two pad bytes to make the struct have a
size which is a multiple of 4.  But the struct doesn't require this.  Neither
would a following struct in an array of structs, as long as the compiler didn't
try accessing these structs as if they contained ints.  The only alignment
requirement obvious to the programmer is that the shorts be on addresses that
are a multiple of two bytes.

To beat a dead horse again, the data members are suitably aligned in
Microsoft's struct.  For the GNU folk to say the extra padding is for data
alignment or is an ABI issue is misleading at best.  It's only an alignment/ABI
issue if the compiler makes it so by generating code that accesses the structs
as if they contained ints, probably for quick copying.  But if that's the case,
I wish they would say that.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32016

Reply via email to