C/C++ Development Suite
Login
Introduction
Summary of changes from 5.54 to 5.55
Summary of changes up to 5.60
Summary of changes from 5.61 to 5.64
Halfword memory access
Packed structs
Inline assembler
C99 pragmas
Constant data
Global data controls
New/changed options

Downloads
Downloads Year 2

   

Packed structs

This version of the compiler adds packed structs, as available in ARM's later compilers.

A packed struct is one in which there is neither padding between fields to ensure the natural alignment of each field, nor trailing padding to ensure the natural alignment of a following struct within an array.

Many applications read data from and write data to networks and computer buses in formats defined by international standards and by other programs executing on different processors. The data format is fixed. Data read and data to be written can be precisely mapped in C using packed structs. However, packed structs cannot support reading values of the wrong endianness.

On the ARM, access to unaligned data can be expensive (taking up to 7 instructions and 2 extra work registers). Data accesses via packed structs should be minimised to avoid performance loss. Generally, internal data structures should not be packed.

There is no command-line option to change the default packing of structures. Packed structures must be specified with a new type qualifier: __packed.

__packed behaves as a type qualifier (like volatile) and may qualify any non floating point type. Floating types may not be fields of packed structures.

A packed struct or union type must be declared explicitly. It is a different type from the corresponding non packed type and its packedness is an attribute of its struct tag (so __packed is more than just a type qualifier). Any variables declared using a packed tag automatically inherit the packed attribute, so __packed does not have to be specified:

    __packed struct P { ... };
    
    struct P pp;    /* pp is a packed struct */

In consequence, the following will be faulted:    

    struct Foo { ... };
    
    __packed struct Foo PackedFoo;    /* illegal */
or
    struct Foo { ... };
    
    typedef __packed struct Foo PackedFoo;    /* illegal */

This ensures that a packed struct can never be assignment compatible with an unpacked struct. This could happen if __packed were merely a type qualifier like volatile and const.

Each field of a packed struct or packed union inherits the packed qualifier.

There are no packed array types. A packed array is simply an array of objects of packed type (there is no inter-element padding).

The effect of casting away __packed is undefined. For example:

    int f(__packed int *px)
    {
        return *(int *)px;    /* undefined behaviour */
    }

A struct (or union) sub-field of a packed struct or union must be declared to have packed struct (or packed union) type.

    struct S {...};
    __packed struct P {...};
    
    struct T {
        struct S ss; /* OK */
        struct P pp; /* OK */
    };
    
    __packed struct Q {
        struct S ss; /* faulted - sub-structs must be packed */
        struct P pp; /* OK */
    };

The substructs are abutted without any intermediate padding, and they contain no internal padding themselves (because they must be packed).

    __packed struct P { char c; int x; };
    __packed struct {
        struct P X;
        char z;
        struct P Y;
    } Q;
    
          <-------------------- Q -------------------->    
          <-------- X -------->   <-------- Y -------->
            
          +---+---+---+---+---+---+---+---+---+---+---+
    byte  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|
          | c | ------x------ | z | c | ------x------ |
          +---+---+---+---+---+---+---+---+---+---+---+  

© 2003/2006 Castle Technology Ltd 32-bit RISC OS