# 5 Fortran, C and C++ Data Types

This chapter describes the scalar and aggregate data types recognized by the PGI Fortran, C, and C++ compilers, the format and alignment of each type in memory, and the range of values each type can take. For more information on IA-32-specific data representation, refer to the System V Application Binary Interface, Processor Supplement, listed in the Preface.

## 5.1 Fortran Data Types

### 5.1.1 Fortran Scalars

A scalar data type holds a single value, such as the integer value 42 or the real value 112.6. Table 5-1 lists scalar data types, their size, format and range. Table 5-2 shows the range and approximate precision for Fortran real data types. Table 5-3 shows the alignment for different scalar data types. The alignments apply to all scalars, whether they are independent or contained in an array, a structure or a union.

Table 5-1 Representation of Fortran Data Types

Fortran
Data Type

Format

Range

INTEGER

2's complement integer

-231 to 231-1

INTEGER*2

2's complement integer

-32768 to 32767

INTEGER*4

same as INTEGER

INTEGER*8

same as INTEGER

-263 to 263-1

LOGICAL

same as INTEGER

true or false

LOGICAL*1

8 bit value

true or false

LOGICAL*2

16 bit value

true or false

LOGICAL*4

same as INTEGER

true or false

LOGICAL*8

same as INTEGER

true or false

BYTE

2's complement

-128 to 127

REAL

Single-precision floating point

10-37 to 1038 (1)

REAL*4

Single-precision floating point

10-37 to 1038 (1)

REAL*8

Double-precision floating point

10-307 to 10308 (1)

DOUBLE PRECISION

Double-precision floating point

10-307 to 10308 (1)

COMPLEX

See REAL

See REAL

DOUBLE COMPLEX

See DOUBLE PRECISION

See DOUBLE PRECISION

COMPLEX*16

Same as above

Same as above

CHARACTER*n

Sequence of n bytes

(1) Approximate value.

The logical constants .TRUE. and .FALSE. are all ones and all zeroes, respectively. Internally, the value of a logical variable is true if the least significant bit is one and false otherwise. When the option -Munixlogical is set, a logical variable with a non-zero value is true and with a zero value is false.

Table 5-2 Real Data Type Ranges

Data Type

Binary Range

Decimal Range

Digits of Precision

REAL

2-126 to 2128

10-37 to 1038

7-8

REAL*8

2-1022 to 21024

10-307 to 10308

15-16

Table 5-3 Scalar Type Alignment

Type

Is Aligned on a

LOGICAL*1

1-byte boundary

LOGICAL*2

2-byte boundary

LOGICAL*4

4-byte boundary

LOGICAL*8

8-byte boundary

BYTE

1-byte boundary

INTEGER*2

2-byte boundary

INTEGER*4

4-byte boundary

INTEGER*8

8-byte boundary

REAL*4

4-byte boundary

REAL*8

8-byte boundary

COMPLEX*8

4-byte boundary

COMPLEX*16

8-byte boundary

### 5.1.2 FORTRAN 77 Aggregate Data Type Extensions

The PGF77 compiler supports de facto standard extensions to FORTRAN 77 which allow for aggregate data types. An aggregate data type consists of one or more scalar data type objects. You can declare the following aggregate data types:

array
consists of one or more elements of a single data type placed in contiguous locations from first to last.
structure
is a structure that can contain different data types. The members are allocated in the order they appear in the definition but may not occupy contiguous locations.
union
is a single location that can contain any of a specified set of scalar or aggregate data types. A union can have only one value at a time. The data type of the union member to which data is assigned determines the data type of the union after that assignment.

The alignment of an array, a structure or union (an aggregate) affects how much space the object occupies and how efficiently the processor can address members. Arrays use the alignment of their members.

Array types
align according to the alignment of the array elements. For example, an array of INTEGER*2 data aligns on a 2 byte boundary.
Structures Unions
align according to the alignment of the most restricted data type of the structure or union. In the next example the union aligns on a 4-byte boundary since the alignment of C, the most restrictive element, is four.
```                STRUCTURE /ASTR/                UNION                         MAP                          INTEGER*2 A        ! 2 bytes                        END MAP                         MAP                          BYTE B             ! 1 byte                         END MAP                        MAP                          INTEGER*4 C        ! 4 bytes                         END MAP                END UNION                END STRUCTURE
```

Structure alignment can result in unused space, called padding, between members of the structure, internal padding, and between the last member and the end of the space occupied by the structure. The padding at the end of the structure is called tail padding.

The offset of a structure member from the beginning of the structure is a multiple of the member's alignment. For example, since an INTEGER*2 aligns on a 2-byte boundary, the offset of an INTEGER*2 member from the beginning of a structure is a multiple of two bytes.

### 5.1.3 Fortran 90 Aggregate Data Types (Derived Types)

The Fortran 90 standard added formal support for aggregate data types. The TYPE statement begins a derived type data specification or declares variables of a specified user-defined type. For example, the following would define a derived type ATTENDEE:

```TYPE ATTENDEE   CHARACTER(LEN=30) NAME   CHARACTER(LEN=30) ORGANIZATION   CHARACTER (LEN=30) EMAILEND TYPE ATTENDEE
```

In order to declare a variable of type ATTENDEE, and access the contents of such a variable, code such as the following would be used:

```TYPE (ATTENDEE) ATTLIST(100). . .ATTLIST(1)%NAME = `JOHN DOE'
```

## 5.2 C and C++ Data Types

### 5.2.1 C and C++ Scalars

Table 5-4 lists C and C++ scalar data types, their size and format. The alignment of a scalar data type is equal to its size. Table 5-5 shows scalar alignments that apply to individual scalars and to scalars that are elements of an array or members of a structure or union. Wide characters are supported (character constants prefixed with an L). The size of each wide character is 4 bytes.

Table 5-4 C/C++ Scalar Data Types

Data Type

Size (bytes)

Format

Range

unsigned char

1

ordinal

0 to 255

[signed] char

1

two's-complement integer

-128 to 127

unsigned short

2

ordinal

0 to 65535

[signed] short

2

two's-complement integer

-32768 to 32767

unsigned int

4

ordinal

0 to 232 -1

[signed] int
[signed] long int

4

two's-complement integer

-231 to 231-1

unsigned long int

4

ordinal

0 to 232-1

[signed] long long [int]

8

two's-complement integer

-263 to 263-1

unsigned long long [int]

8

ordinal

0 to 264-1

float

4

IEEE single-precision
floating-point

10-37 to 1038 (1)

double

8

IEEE double-precision floating-point

10-307 to 10308 (1)

long double

8

IEEE double-precision floating-point

10-307 to 10308 (1)

bit field(2)
(unsigned value)

1 to 32 bits

ordinal

0 to 2size-1, where size is the number of bits in the bit field

bit field(2)
(signed value)

1 to 32 bits

two's complement integer

-2size-1 to 2size-1-1, where size is the number of bits in the bit field

pointer

4

0 to 232-1

enum

4

two's complement integer

-231 to 231-1

(1) Approximate value.
(2) Bit fields occupy as many bits as you assign them, up to 4 bytes, and their length need not be a
multiple of 8 bits (1 byte).

Table 5-5 Scalar Alignment

Data Type

Alignment

char

is aligned on a 1-byte boundary.*

short

is aligned on a 2-byte boundary.*

[long] int

is aligned on a 4-byte boundary.*

enum

is aligned on a 4-byte boundary.

pointer

is aligned on a 4-byte boundary.

float

is aligned on a 4-byte boundary.

double

is aligned on an 8-byte boundary.

long double

is aligned on an 8-byte boundary.

(*) signed or unsigned

### 5.2.2 C and C++ Aggregate Data Types

An aggregate data type consists of one or more scalar data type objects. You can declare the following aggregate data types:

array
consists of one or more elements of a single data type placed in contiguous locations from first to last.
class
(C++ only) is a class that defines an object and its member functions. The object can contain fundamental data types or other aggregates including other classes. The class members are allocated in the order they appear in the definition but may not occupy contiguous locations.
struct
is a structure that can contain different data types. The members are allocated in the order they appear in the definition but may not occupy contiguous locations. When a struct is defined with member functions, its alignment issues are the same as those for a class.
union
is a single location that can contain any of a specified set of scalar or aggregate data types. A union can have only one value at a time. The data type of the union member to which data is assigned determines the data type of the union after that assignment.

### 5.2.3 Class and Object Data Layout

Class and structure objects with no virtual entities and with no base classes, that is just direct data field members, are laid out in the same manner as C structures. The following section describes the alignment and size of these C-like structures. C++ classes (and structures as a special case of a class) are more difficult to describe. Their alignment and size is determined by compiler generated fields in addition to user-specified fields. The following paragraphs describe how storage is laid out for more general classes. The user is warned that the alignment and size of a class (or structure) is dependent on the existence and placement of direct and virtual base classes and of virtual function information. The information that follows is for informational purposes only, reflects the current implementation, and is subject to change. Do not make assumptions about the layout of complex classes or structures.

All classes are laid out in the same general way, using the following pattern (in the sequence indicated):

• First, storage for all of the direct base classes (which implicitly includes storage for non-virtual indirect base classes as well):
• When the direct base class is also virtual, only enough space is set aside for a pointer to the actual storage, which appears later.
• In the case of a non-virtual direct base class, enough storage is set aside for its own non-virtual base classes, its virtual base class pointers, its own fields, and its virtual function information, but no space is allocated for its virtual base classes.
Next, storage for the class's own fields.
• Next, storage for virtual function information (typically, a pointer to a virtual function table).
• Finally, storage for its virtual base classes, with space enough in each case for its own non-virtual base classes, virtual base class pointers, fields, and virtual function information.

### 5.2.4 Aggregate Alignment

The alignment of an array, a structure or union (an aggregate) affects how much space the object occupies and how efficiently the processor can address members. Arrays use the alignment of their members.

Arrays
align according to the alignment of the array elements. For example, an array of short data type aligns on a
2-byte boundary.
structures and unions
align according to the most restrictive alignment of the enclosing members. For example the union un1 below aligns on a 4-byte boundary since the alignment of c, the most restrictive element, is four:
```         union un1 {               short a;    /* 2 bytes */               char  b;    /* 1 byte  */               int   c;    /* 4 bytes */         };
```

Structure alignment can result in unused space, called padding. Padding between members of a structure is called internal padding. Padding between the last member and the end of the space occupied by the structure is called tail padding. Figure 5-1 illustrates structure alignment. Consider the following structure:

```struct strc1 {  char  a;  /* occupies byte 0             */  short b;  /* occupies bytes 2 and 3      */  char  c;  /* occupies byte 4             */  int   d;  /* occupies bytes 8 through 11 */};
```

Figure 5-1 Internal Padding in a Structure

Figure 5-2 below shows how tail padding is applied to a structure aligned on a doubleword boundary.

```struct strc2{  int     m1[4]; /* occupies bytes 0 through 15  */  double  m2;    /* occupies bytes 16 through 23 */  short   m3;    /* occupies bytes 24 and 25    */} st;
```

### 5.2.5 Bit-field Alignment

Bit-fields have the same size and alignment rules as other aggregates, with several additions to these rules:

• Bit-fields are allocated from right to left.
• A bit-field must entirely reside in a storage unit appropriate for its type. Bit-fields never cross unit boundaries.
• Bit-fields may share a storage unit with other structure/union members, including members that are not bit-fields.
• Unnamed bit-field's types do not affect the alignment of a structure or union.
• Items of [signed/unsigned] long long type may not appear in field declarations.

Figure 5-2 Tail Padding in a Structure

### 5.2.6 Other Type Keywords in C and C++

The void data type is neither a scalar nor an aggregate. You can use void or void* as the return type of a function to indicate the function does not return a value, or as a pointer to an unspecified data type, respectively.

The const and volatile type qualifiers do not in themselves define data types, but associate attributes with other types. Use const to specify that an identifier is a constant and is not to be changed. Use volatile to prevent optimization problems with data that can be changed from outside the program, such as memory-mapped I/O buffers.