176

It is C language.It is written that:

typedef struct __attribute__((packed, aligned(4))) Ball {
    float2 delta;
    float2 position;
    //float3 color;
    float size;
    //int arcID;
    //float arcStr;
} Ball_t;
Ball_t *balls;

Please tell me what is the meaning of it,and how to use this keyword.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Aaron Lee
  • 2,060
  • 2
  • 15
  • 20
  • 6
    It's a ["type attribute"](http://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html) .. (I found this with "C attribute packed" in Google. Surely others can at least do as good!) –  Aug 02 '12 at 03:01
  • 1
    See [this question](http://stackoverflow.com/q/8568432/827263) -- though with `aligned(4)` you probably don't have much to worry about. – Keith Thompson Aug 02 '12 at 04:07

3 Answers3

220

Before answering, I would like to give you some data from Wiki


Data structure alignment is the way data is arranged and accessed in computer memory. It consists of two separate but related issues: data alignment and data structure padding.

When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (e.g. 4 byte chunks on a 32-bit system). Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system's performance due to the way the CPU handles memory.

To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding.


gcc provides functionality to disable structure padding. i.e to avoid these meaningless bytes in some cases. Consider the following structure:

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}sSampleStruct;

sizeof(sSampleStruct) will be 12 rather than 8. Because of structure padding. By default, In X86, structures will be padded to 4-byte alignment:

typedef struct
{
     char Data1;
     //3-Bytes Added here.
     int Data2;
     unsigned short Data3;
     char Data4;
     //1-byte Added here.

}sSampleStruct;

We can use __attribute__((packed, aligned(X))) to insist particular(X) sized padding. X should be powers of two. Refer here

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}__attribute__((packed, aligned(1))) sSampleStruct;  

so the above specified gcc attribute does not allow the structure padding. so the size will be 8 bytes.

If you wish to do the same for all the structures, simply we can push the alignment value to stack using #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)
Kenn Sebesta
  • 7,485
  • 1
  • 19
  • 21
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • 13
    If memory store data in 4 byte chunks then why its not adding 2 padding bytes to the unsigned short(its 2 byte long) ? or compiler just add padding bytes to 1st and last members of structure ? can you please clarify it. – User Mar 06 '14 at 11:33
  • 8
    @User Plz refer this too. If you still not clear, plz come for help http://stackoverflow.com/questions/11772553/why-padding-is-not-happening-in-this-case – Jeyaram Mar 06 '14 at 11:47
  • 1
    Whoever said these padding bytes are meaningless does not know that misaligned data access is an oddity of x86 architecture. These bytes are necessary to avoid exceptions when processor tries to load - say an integer - data which straddles its natural alignment boundary. – Tanveer Badar Nov 20 '19 at 06:27
  • 7
    @TanveerBadar they meant that the *values* of the padding bytes are meaningless, not their presence. – Len Sep 22 '20 at 23:36
  • Just to clarify, if we had another char Data5 at the end of the struct, will there be padding ? (using 'packed, aligned(4)' ) – schanti schul Nov 24 '21 at 08:26
  • @schantischul Yes. still Data1 at the beginning needs to be aligned right? – Jeyaram Nov 24 '21 at 15:43
  • Where will that padding be? – schanti schul Nov 25 '21 at 07:36
  • I'm slightly confused on the explanation for the 8/12 thing... aren't 8 bytes also divisible by 4? I'm not sure why the padding occurs in that case? Is it because Data1 has to be divisible by 4? @Jeyaram – Mor Elmaliach Nov 29 '21 at 10:06
  • 1
    @MorElmaliach Padding happens wrt accessibility of members of the struct. Read the accepted answer of https://stackoverflow.com/questions/11772553/why-padding-is-not-happening-in-this-case thread for more clarity. – Jeyaram Nov 29 '21 at 10:44
119
  • packed means it will use the smallest possible space for struct Ball - i.e. it will cram fields together without padding
  • aligned means each struct Ball will begin on a 4 byte boundary - i.e. for any struct Ball, its address can be divided by 4

These are GCC extensions, not part of any C standard.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • Can you please tell if both, do we add bytes in the end only? – schanti schul Nov 23 '21 at 13:57
  • What do you mean with "4 byte boundary"? What does that mean? – user2762996 Dec 28 '21 at 15:15
  • @schantischul No, the compiler is free to add these bytes (they are referred to as _padding_) anywhere it chooses. They are most often put adjacent to `char` arrays or other data types that are < 32 bits in length (or 64 bits) - depending on the target processor. – sherrellbc Jan 17 '22 at 15:42
  • @user2762996 A "boundary" is an addressing concept. Is it often most efficient (in time and program space) to _align_ members of a structure to the "word size" of the target processor. This is often 32 or 64 bits in modern computing. In fact, some processors of old did not support _unaligned_ accesses to memory and would trigger execution conditions (though behavior could be emulated in the exception handler). Mathematically, an address that is aligned to some arbitrary boundary is said to be "modulo 0" that size. – sherrellbc Jan 17 '22 at 15:46
  • That is, `aligned4 = !!(addr % 4);` will 1 for any address ending in 0, 1, 2, or 3. Similarly `aligned8 = !!(addr & 8);` will be 1 for any address ending in 0 through 7. These two expressions represent 4 (32 bit) or 8 (64 bit) byte alignments. [Try it out](https://onlinegdb.com/wtpXCaZCgo). – sherrellbc Jan 17 '22 at 15:54
29

The attribute packed means that the compiler will not add padding between fields of the struct. Padding is usually used to make fields aligned to their natural size, because some architectures impose penalties for unaligned access or don't allow it at all.

aligned(4) means that the struct should be aligned to an address that is divisible by 4.

ken2k
  • 48,145
  • 10
  • 116
  • 176
Julian Stecklina
  • 1,271
  • 1
  • 10
  • 24