4.2.4.8 Structure type packing

In the CC-RH, the alignment of structure members can be specified at the C language level. This function is equivalent to the -Xpack option, however, the structure type packing directive can be used to specify the alignment value in any location in the C source.

Caution

The data area can be reduced by packing a structure type, but the program size increases and the execution speed is degraded.

(1)

Format of structure type packing

The structure type packing function is specified in the following format.

#pragma pack [(][1|2|4][)]

 

#pragma pack changes to an alignment value of the structure member upon the occurrence of this directive. The numeric value is called the packing value and the specifiable numeric values are 1, 2, 4. When the numeric value is not specified, the setting is the default alignment.Since this directive becomes valid upon occurrence, several directives can be described in the C source.

Example

#pragma pack 1  /*structure member aligned using 1-byte alignment*/
struct  TAG {
        char    c;
        int     i;
        short   s;
};

(2)

Rules of structure type packing

The structure members are aligned in a form that satisfies the condition whereby members are aligned according to whichever is the smaller value: the structure type packing value or the member's alignment value.

For example, if the structure type packing value is 2 and member type is int type, the structure members are aligned in 2-byte alignment.

Example

struct  S {
        char    c;  /*satisfies 1-byte alignment condition*/
        int     i;  /*satisfies 4-byte alignment condition*/
};
 
#pragma pack 1
struct  S1 {
        char    c;  /*satisfies 1-byte alignment condition*/
        int     i;  /*satisfies 1-byte alignment condition*/
};
 
#pragma pack 2
struct  S2 {
        char    c;  /*satisfies 1-byte alignment condition*/
        int     i;  /*satisfies 2-byte alignment condition*/
};
 
struct  S   sobj;   /*size of 8 bytes*/
struct  S1  s1obj;  /*size of 5 bytes*/
struct  S2  s2obj;  /*size of 6 bytes*/

 

(3)

Union

A union is treated as subject to packing and is handled in the same manner as structure type packing.

Example 1.

union   U {
        char c;
        int i;
};
 
#pragma pack 1
union   U1 {
        char c;
        int i;
};
 
#pragma pack 2
union   U2 {
        char c;
        int i;
};
 
union   U   uobj;   /*size of 4 bytes*/
union   U1  u1obj;  /*size of 4 bytes*/
union   U2  u2obj;  /*size of 4 bytes*/

Example 2.

union   U {
        int i:7;
};
 
#pragma pack 1
union   U1 {
        int i:7;
};
 
#pragma pack 2
union   U2 {
        int i:7;
};
 
union   U   uobj;   /*size of 4 bytes*/
union   U1  u1obj;  /*size of 1 byte*/
union   U2  u2obj;  /*size of 2 bytes*/

(4)

Bit field

Data is allocated to the area of the bit field element as follows.

(a)

When the structure type packing value is equal to or larger than the alignment condition value of the member type

Data is allocated in the same manner as when the structure type packing function is not used. That is, if the data is allocated consecutively and the resulting area exceeds the boundary that satisfies the alignment condition of the element type, data is allocated from the area satisfying the alignment condition.

(b)

When the structure type packing value is smaller than the alignment condition value of the element type

-

If data is allocated consecutively and results in the number of bytes including the area becoming larger than the element type
The data is allocated in a form that satisfies the alignment condition of the structure type packing value.

-

Other conditions
The data is allocated consecutively.

Example

struct  S {
        short   a:7;    /*0 to 6th bit*/
        short   b:7;    /*7 to 13th bit*/
        short   c:7;    /*16 to 22nd bit (aligned to 2-byte boundary)*/
        short   d:15;   /*32 to 46th bit (aligned to 2-byte boundary)*/
} sobj;
 
#pragma pack 1
struct  S1 {
        short   a:7;    /*0 to 6th bit*/
        short   b:7;    /*7 to 13th bit*/
        short   c:7;    /*14 to 20th bit*/
        short   d:15;   /*24 to 38th bit  (aligned to byte boundary)*/
} s1obj;

 

(5)

Alignment condition of top structure object

The alignment condition of the top structure object is the smaller of the alignment value and packing value of the structure object.

(6)

Size of structure objects

Perform packing so that the size of structure objects becomes a multiple value of whichever is the smaller value: the structure alignment condition value or the structure packing value.

Example 1.

struct  S {
        int     i;
        char    c;
};
 
#pragma pack 1
struct  S1 {
        int     i;
        char    c;
};
 
#pragma pack 2
struct  S2 {
        int     i;
        char    c;
};
 
struct  S   sobj;   /*size of 8 bytes*/
struct  S1  s1obj;  /*size of 5 bytes*/
struct  S2  s2obj;  /*size of 6 bytes*/

 

 

Example 2.

struct  S {
        int     i;
        char    c;
};
struct  T {
        char    c;
        struct  S   s;
};
 
#pragma pack 1
struct  S1 {
        int     i;
        char    c;
};
struct  T1 {
        char    c;
        struct  S1  s1;
};
 
#pragma pack 2
struct  S2 {
        int     i;
        char    c;
};
struct  T2 {
        char    c;
        struct  S2  s2;
};
 
struct  T   tobj;   /*size of 12 bytes*/
struct  T1  t1obj;  /*size of 6 bytes*/
struct  T2  t2obj;  /*size of 8 bytes*/

 

(7)

Size of structure array

The size of the structure object array is a value that is the sum of the number of elements multiplied to the size of structure object.

Example

struct  S {
        int     i;
        char    c;
};
 
#pragma pack 1
struct  S1 {
        int     i;
        char    c;
};
 
#pragma pack 2
struct  S2 {
        int     i;
        char    c;
};
 
struct  S   sobj[2];    /*size of 16 bytes*/
struct  S1  s1obj[2];   /*size of 10 bytes*/
struct  S2  s2obj[2];   /*size of 12 bytes*/

 

(8)

Area between objects

For example, sobj.c, sobj.i, and cobj may be allocated consecutively without a gap in the following source program (the allocation order of sobj and cobj is not guaranteed).

Example

#pragma pack 1
struct  S {
        char    c;
        int     i;
} sobj;
char    cobj;

 

(9)

Notes concerning structure packing function

(a)

Specification of the -Xpack option and #pragma pack directive at the same time

If the -Xpack option is specified when structure packing is specified with the #pragma pack directive in the C source, the specified option value is applied to all the structures until the first #pragma pack directive appears. After this, the value of the #pragma pack directive is applied.

If you subsequently write #pragma pack (no value), then the value specified with this option is applied following that line.

Example

When -Xpack=4 is specified

struct  S2 {...};   /*Packing value is specified as 4 in option. 
                      -Xpack=4 option is valid: packing value is 4.*/
 
#pragma pack 2      /*Packing is specified as 2 in #pragma directive
struct  S1 {...};     pragma pack(2) is valid: packing value is 2.*/
 
#pragma pack        /*No specification of packing value with #pragma directive
struct  S2_2 {...};   -Xpack=4 option is valid: packing value is 4.*/

(b)

Structure packing value and alignment value of members

Structure members are arranged so that the alignment conditions match the smaller of the structure's packing value and the members' alignment value. For example, if the structure's packing value is 2, and a member type is long, then it is ordered to meet the 2-byte alignment condition.

Example

struct S {
        char    c;      /*Meets 1-byte alignment condition*/
        long    i;      /*Meets 4-byte alignment condition*/
};
 
#pragma pack(1)
struct S1 {
        char    c;      /*Meets 1-byte alignment condition*/
        long    i;      /*Meets 1-byte alignment condition*/
};
 
#pragma pack(2)
struct S2 {
        char    c;      /*Meets 1-byte alignment condition*/
        long    i;      /*Meets 2-byte alignment condition*/
};
 
struct S        sobj;   /*Size 8 bytes*/
struct S1       s1obj;  /*Size 5 bytes*/
struct S2       s2obj;  /*Size 6 bytes*/

(c)

Nested #pragma pack specification

Specify nested #pragma pack specifications for a structure as follows.

A warning is output for structure or union members with different alignment.

The alignment of members generating the warning will be in accordance with the #pragma pack statements in the source code.

Example

#pragma pack 1
struct ST1
{
        char    c;
#pragma pack 4
        struct ST4      //size=8, align=4 (Type is 4)
        {
            char    c;  //offset=1
            short   s;  //offset=3
            int     i;  //offset=5
        } st4;          //size=8, align=1 (1, because this is an ST1 member)
                        //Warning at location of member st4
        int i;
} st1;                  //size=13, align=1

[Caution]

When -Xpack=1 or 2 or #pragma pack 1 or 2 is specified for a structure or union, its members cannot be accessed using a pointer.

#pragma   pack  1
struct st {
    char  x;
    int  y;
} ST;
int *p = &ST.y; /* The ST.y address may be an odd value. */
void func(void){
    ST.y =1;    /* Can be accessed correctly. */
    *p = 1;     /* Cannot be accessed correctly in some cases. */
}