Personal tools
PGI Workstation User's Guide - 5 Fortran, C and C++ Data Types
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 |
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
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) EMAIL
END 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 |
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 |
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) |
1 to 32 bits |
ordinal |
0 to 2size-1, where size is the number of bits in the bit field |
bit
field(2) |
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 |
address |
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. |
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 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.
<< " border=0> > " border=0>