• Aucun résultat trouvé

Derived Data Types

The following objects are derived data types. The sizes of each data type (or the calculation used to determine the size) are listed.

Pointers 32-bits.

Arrays (Number of elements)*(Size of one element).

Structures Sum of the sizes of each member. (Members, as well as the structure itself, may be padded for alignment.)

Unions Size of the largest member. (This member, as well as the union itself, may be padded for alignment.)

Enum types 1, 2, or 4 bytes depending on the constant values of the elements.

Pointers

Pointers are addresses which point to stored values. Pointers occupy four bytes and are aligned on four-byte boundaries (two-byte boundaries for the 68000 and 68332). The following program is a simple example of how pointers are used.

main()

Arrays are made up of a fixed number of elements of the same type.

Multi-dimensional arrays can be thought of as arrays of arrays (of arrays, etc.) where each array represents a single dimension. Index values for each dimension are used to access the elements of a multi-dimensional array.

Chapter 3: Internal Data Representation Derived Data Types

The amount of storage allocated for an array is the sum of the space used by all its elements. An array is aligned on the alignment boundary of its elements. For example, a short array with 10 elements would use 20 bytes and be aligned on a two byte boundary.

The first element of a one-dimensional array (index equals zero) is located at the lowest address of the storage allocated for the array. Elements of multi-dimensional arrays are stored in row-major order (in other words, the rightmost index changes more rapidly with successive memory locations).

The following program shows some simple arrays.

float fpns[10]; /* 10*4 = 40 Bytes of storage allocated */

main() {

int array[4][7]; /* 4*7*4 = 112 Bytes allocated */

int i, j; /* on the stack. */

fpns[1] = 1.0;

for (i = 0; i < 4; i++)

for (j = 0; j < 7; j++) array[i][j] = 0;

}

Chapter 3: Internal Data Representation Derived Data Types

Strings

Strings are a sequence of characters or escape sequences enclosed in double quotes ("). Strings may be used in two distinct contexts. The first is in C program

statements or as intitializers of type char * where they are treated as if they are of type "const char *". For example:

char *p, *q = "abc";

p = "xyz";

When used in such a context, the compiler places the string, together with an additional NULL (0) termination character, in the named CONST linker section (named "const" by default).

The second context in which strings may be used is as initializers of arrays of char.

If the initialized array is an automatic, the initialization occurs at run-time, and the compiler places the string and NULL terminator in the named CONST linker section just as above. If, however, the array being initialized is a static, the initialization occurs at load-time (or is in ROM). For example:

const char string[] = "abcdefghi";

When a string is used to initialize an array, the compiler places the initialized array in either the named DATA linker section (if the array’s type is not "const") or in the named CONST linker section (if the array’s type is "const"). A terminating NULL (0) character is appended to the string only if there is room in the declared array (or if it is "open" as above).

Note Trying to change the value of a string constant may cause unwanted side effects.

The reason for this is explained in the "Optimizations" chapter.

The compiler accepts hexadecimal escape sequences of unlimited length. The example below is interpreted as a single hex value:

*str = "\x064f";

In order to produce the string "df", you could modify the string in the following way:

*str = "\x064" "f";

Chapter 3: Internal Data Representation Derived Data Types

Structures

Structures are named collections of members. Structure members may be of different types, they may be specified as bit fields, or they may even be pointers to the structure in which they are defined (self-referential structures).

Structures may be passed as parameters to and returned from functions. (See the

"Stack Frame Management" section of the "Compiler Generated Assembly Code"

chapter for more information on how structures are passed to and returned from functions.)

The amount of storage allocated for a structure is the sum of the space required by all its members, the alignment padding between members, and padding at the end of the structure to make its size a multiple of four (two) bytes. For example, a structure whose members are a char, an int, and a double would be allocated 16 bytes (three bytes following the char are "wasted" to align the int). (For the 68000 and 68332, 14 bytes are allocated—one byte following the char is "wasted" to align the int). Members are located in the allocated space in the order that they are declared.

An example of a simple structure follows.

struct example { /* 16 bytes of storage allocated at 4-byte boundary. */

For the 68000 and 68332 processors, struct example uses 14 bytes of storage allocated at a 2-byte boundary. int i begins at the 3rd byte of the structure and double d begins at the 7th byte of the structure.

See the "Alignment Considerations" section for information on how the -Q option affects member alignment.

Chapter 3: Internal Data Representation Derived Data Types

Bit Fields

Bit fields are structure or union members which are defined as a number of bits. A colon separates the length of a bit field from the declarator. Bit fields can be signed (declared as plain integral types) or unsigned (declared as unsigned integral types).

All integral types are allowed in bit field declarations, but are converted to int or unsigned int. The high order bit of a signed bit field is the sign bit.

Bit fields are packed from the high-order bits to the low-order bits in the words of memory they occupy. Bit padding can be generated by omitting the name from the bit field declaration. Consecutive bit fields are packed adjacently regardless of integer boundaries. However, a bit field with a specified width of zero will cause the following bit field to start on the next int (double word) (short word for the 68000) boundary.

Examples of bit field declarations follow.

struct {

Unions

Unions are like structures except that each member has a zero offset from the beginning of the union. Unions provide a way to access the same memory locations in more than one format. A simple example of a union is shown below.

union {

Accessing int and char members or int and short members will yield different results due to the byte ordering of data on the 68000. See the "Byte Ordering"

section which follows.

Documents relatifs