# <!-- var kmNextPage = "armcc_chr1359124231193.htm"; var kmPrevPage = "armcc_chr1359124230710.htm"; var kmNextPageTitle = "Compiler support for floating-point arithmetic"; var kmPrevPageTitle = "Unaligned Load Register (LDR) instructions generat"; var kmBreadCrumbs = "<a href=\"default.htm\">Home</a> &raquo; <a href=\"armcc_chr1359124220881.htm\">Compiler Coding Practices</a> &raquo; Comparisons of an unpacked struct, a __packed stru"; kmSetupPaging (); kmNavButtons(); //--> Comparisons of an unpacked struct, a __packed struct, and a struct with individually __packed fields, and of a __packed struct and a #pragma packed struct

## 4.40 Comparisons of an unpacked struct, a __packed struct, and a struct with individually __packed fields, and of a __packed struct and a #pragma packed struct

These comparisons illustrate the differences between the methods of packing structures.

## Comparison of an unpacked `struct`, a __packed `struct`, and a `struct` with individually __packed fields

The differences between not packing a `struct`, packing an entire `struct`, and packing individual fields of a `struct` are illustrated by the three implementations of a `struct` shown in the following table.

Table 4-10 C code for an unpacked struct, a packed struct, and a struct with individually packed fields

Unpacked struct __packed struct __packed fields
```struct foo
{
char one;
short two;
char three;
int four;
} c;
```
```__packed struct foo
{
char one;
short two;
char three;
int four;
} c;
```
```struct foo
{
char one;
__packed short two;
char three;
int four;
} c;
```
In the first implementation, the `struct` is not packed. In the second implementation, the entire structure is qualified as `__packed`. In the third implementation, the `__packed` attribute is removed from the structure and the individual field that is not naturally aligned is declared as `__packed`.
The following table shows the corresponding disassembly of the machine code produced by the compiler for each of the sample implementations of the preceding table, where the C code for each implementation has been compiled using the option `-O2`.

Table 4-11 Disassembly for an unpacked struct, a packed struct, and a struct with individually packed fields

Unpacked struct __packed struct __packed fields
```; r0 contains address of c
; char one
LDRB    r1, [r0, #0]
; short two
LDRSH   r2, [r0, #2]
; char three
LDRB    r3, [r0, #4]
; int four
LDR     r12, [r0, #8]
```
```; r0 contains address of c
; char one
LDRB  r1, [r0, #0]
; short two
LDRB  r2, [r0, #1]
LDRSB r12, [r0, #2]
ORR   r2, r12, r2, LSL #8
; char three
LDRB  r3, [r0, #3]
; int four
```
```; r0 contains address of c
; char one
LDRB  r1, [r0, #0]
; short two
LDRB  r2, [r0, #1]
LDRSB r12, [r0, #2]
ORR   r2, r12, r2, LSL #8
; char three
LDRB  r3, [r0, #3]
; int four
LDR   r12, [r0, #4]
```

### Note

The `-Ospace` and `-Otime` compiler options control whether accesses to unaligned elements are made inline or through a function call. Using `-Otime` results in inline unaligned accesses. Using `-Ospace` results in unaligned accesses made through function calls.
In the disassembly of the unpacked `struct` example above, the compiler always accesses data on aligned word or halfword addresses. The compiler is able to do this because the `struct` is padded so that every member of the `struct` lies on its natural size boundary.
In the disassembly of the `__packed` `struct` example above, fields `one` and `three` are aligned on their natural size boundaries by default, so the compiler makes aligned accesses. The compiler always carries out aligned word or halfword accesses for fields it can identify as being aligned. For the unaligned field `two`, the compiler uses multiple aligned memory accesses (`LDR`/`STR`/`LDM`/`STM`), combined with fixed shifting and masking, to access the correct bytes in memory. The compiler calls the ARM Embedded Application Binary Interface (AEABI) runtime routine `__aeabi_uread4` for reading an unsigned word at an unknown alignment to access field `four` because it is not able to determine that the field lies on its natural size boundary.
In the disassembly of the `struct` with individually packed fields example above, fields `one`, `two`, and `three` are accessed in the same way as in the case where the entire `struct` is qualified as `__packed`. In contrast to the situation where the entire `struct` is packed, however, the compiler makes a word-aligned access to the field `four`. This is because the presence of the ```__packed short``` within the structure helps the compiler to determine that the field `four` lies on its natural size boundary.

## Comparison of a __packed `struct` and a #pragma packed `struct`

The differences between a `__packed` `struct` and a `#pragma pack`ed `struct` are illustrated by the two implementations of a `struct` shown in the following table.

Table 4-12 C code for a packed struct and a pragma packed struct

__packed struct #pragma packed struct
```__packed struct foobar
{
char x;
short y[10];
};
short get_y0(struct foobar *s)
{
return *s->y;
}
short *get_y(struct foobar *s)
{
return s->y;    // Compile error
}
```
```#pragma push
#pragma pack(1)
struct foobar
{
char x;
short y[10];
};
#pragma pop
short get_y0(struct foobar *s)
{
return *s->y;
}
short *get_y(struct foobar *s)
{
return s->y;    // No error
// depending on use of result
}
```
In the first implementation, taking the address of a field in a `__packed` `struct` or a `__packed` field in a `struct` yields a `__packed` pointer, and the compiler generates a type error if you try to implicitly cast this to a non-`__packed` pointer. In the second implementation, in contrast, taking the address of a field in a `#pragma pack`ed `struct` does not yield a `__packed`-qualified pointer. However, the field might not be properly aligned for its type, and dereferencing such an unaligned pointer results in Undefined behavior.