3

I'm working with an struct compiled for a 32bit ARM processor.

typedef struct structure {
   short a;
   char b;
   double c;
   int d;
   char e;
}structure_t;

If I use nothing, __attribute__ ((aligned (8))) or__attribute__ ((aligned (4))) I get the same results in terms of structure size and elements offset. Total size is 24. So I think it is always aligning to 8 (offsets are for both a=0 , b=2, c=8, d=16, e=20).

Why is 8 the default alignment chosen by the compiler? Should not it be 4 because is a 32 word processor?

Thanks in advance mates.

ferdepe
  • 510
  • 1
  • 6
  • 21
  • Whatever is aligned to 8 bytes is alligned to 4 as well. So "same results" are not impossible. – Eugene Sh. Oct 25 '18 at 13:49
  • 1
    @EugeneSh. but `c` should be at offset 4 for an alignement of 4. – Jabberwocky Oct 25 '18 at 13:51
  • @Jabberwocky Depends where this attribute is placed. Looks like alignment is confused with padding here. – Eugene Sh. Oct 25 '18 at 13:52
  • @EugeneSh. what is your point? I suppose that for a 4 byte allignment the total size will be 20 and c offset will be at 4 instead of 8. – ferdepe Oct 25 '18 at 13:52
  • @EugeneSh. I put alligment attribute just before `structure_t` – ferdepe Oct 25 '18 at 13:53
  • 1
    @ferdepe you should make that clear in the question. – Jabberwocky Oct 25 '18 at 13:54
  • 1
    And you should note, that this attribute is specifying the *minimum* alignment. Also structure fields are aligned to the field with the largest alignment requirement. Which is `double` in your case. – Eugene Sh. Oct 25 '18 at 13:55
  • 1
    Here is related question (if not a duplicate): https://stackoverflow.com/questions/21219130/is-8-byte-alignment-for-double-type-necessary – Eugene Sh. Oct 25 '18 at 13:59
  • 2
    Generally fields will be aligned to an address that can be divided by their size, so an 8-byte field, say, is 8-byte aligned, and so on. This is to aid performance, e.g. to prevent loads and stores that cross cache lines. – 500 - Internal Server Error Oct 25 '18 at 13:59
  • The aligned attribute is misleading, you specify when you *stop* trying to keep members aligned. The alignment requirement for the struct is 8 due to the *double* member. Setting the attribute to 4 (thus telling the compiler to not try to align the double) makes no difference by accident, the c member happens to be aligned to 8 anyway. Drop the b member to see a difference. And try 1. – Hans Passant Oct 25 '18 at 14:11

1 Answers1

2

The aligned attribute only specifies a minimum alignment, not an exact one. From gcc documentation:

The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well.

And the natural alignment of double is 8 on your platform, so that is what is used.

So to get what you want you need to combine the aligned and packed attributes. With the following code, c has offset 4 (tested using offsetof).

typedef struct structure {
   short a;
   char b;
   __attribute__((aligned(4))) __attribute__((packed)) double c;
   int d;
   char e;
} structure_t;
Samuel Peter
  • 4,136
  • 2
  • 34
  • 42
  • 1
    Perfect! That's the answer to my question :) With the reference and your example finally I get it! – ferdepe Oct 25 '18 at 14:29