Sun WorkShop Compiler C 5.0 User's Guide

Appendix A ANSI/ISO C Data Representations

This appendix describes how ANSI C represents data in storage and the mechanisms for passing arguments to functions. It is intended as a guide to programmers who want to write or use modules in languages other than C and have those modules interface to C code.

Storage Allocation

Table A-1 shows the data types and how they are represented.

Table A-1 Storage Allocation for Data Types

Data Type 

Internal Representation 

char elements

A single 8-bit byte aligned on a byte boundary. 

short integers

Halfword (two bytes or 16 bits), aligned on a two-byte boundary 

int and long

32 bits on v8 (four bytes or one word), aligned on a four-byte boundary 

64 bits on v9 (four bytes or one word) aligned on an eight-byte boundary) 

long long [long long is not available in -Xc mode.]

(SPARC) 64 bits (eight bytes or two words), aligned on an eight-byte boundary

(Intel) 64 bits (eight bytes or two words), aligned on a four-byte boundary

float

32 bits (four bytes or one word), aligned on a four-byte boundary. A float has a sign bit, 8-bit exponent, and 23-bit fraction.

double

64 bits (eight bytes or two words), aligned on an eight-byte boundary (SPARC) or aligned on a four-byte boundary (Intel). A double element has a sign bit, an 11-bit exponent and a 52-bit fraction.

long double

v8 (SPARC) 128 bits (16 bytes or four words), aligned on an eight-byte boundary. A long double element has a sign bit, a 15-bit exponent and a 112-bit fraction.

 

v9 (SPARC) 128 bits (16 bytes or four words), aligned on a 16 byte boundary. A long double element has a sign bit, a 15-bit exponent and a 112-bit fraction.

 

(Intel) 96 bits (12 bytes or three words) aligned on a four-byte boundary. A long double element has a sign bit, a 16-bit exponent, and a 64-bit fraction. 16 bits are unused.

Data Representations

Bit numberings of any given data element depend on the architecture in use: SPARCstation(TM) machines use bit 0 as the least significant bit, with byte 0 being the most significant byte. The tables in this section describe the various representations.

Integer Representations

Integer types used in ANSI C are short, int, long, and long long:

Table A-2 Representation of short

Bits 

Content 

8 - 15 

Byte 0 (SPARC)

Byte 1 (Intel)

0 - 7 

Byte 1 (SPARC)

Byte 0 (Intel)

Table A-3 Representation of int

Bits 

Content  

24 - 31 

Byte 0 (SPARC)

Byte 3 (Intel)

16 - 23 

Byte 1 (SPARC)

Byte 2 (Intel)

8 - 15 

Byte 2 (SPARC)

Byte 1 (Intel)

0 - 7 

Byte 3 (SPARC)

Byte 0 (Intel)

Table A-4 Representation of long on Intel and SPARC v8 versus SPARC v9

Bits 

Content  

24 - 31 

Byte 0 (SPARC) v8

Byte 4 (SPARC) v9

Byte 3 (Intel)

16 - 23 

Byte 1 (SPARC) v8

Byte 5 (SPARC) v9

Byte 2 (Intel)

8 - 15 

Byte 2 (SPARC) v8

Byte 6 (SPARC) v9

Byte 1 (Intel)

0 - 7 

Byte 3 (SPARC) v8

Byte 7 (SPARC) v9

Byte 0 (Intel)

Table A-5 Representation of long long [long long is not available in -Xc mode.]

Bits 

Content 

56 - 63 

Byte 0 (SPARC)

Byte 7 (Intel)

48 - 55 

Byte 1 (SPARC)

Byte 6 (Intel)

40 - 47 

Byte 2 (SPARC)

Byte 5 (Intel)

32 - 39 

Byte 3 (SPARC)

Byte 4 (Intel)

24 - 31 

Byte 4 (SPARC)

Byte 3 (Intel)

16 - 23 

Byte 5 (SPARC)

Byte 2 (Intel)

8 - 15 

Byte 6(SPARC)

Byte 1 (Intel)

0 - 7 

Byte 7 (SPARC)

Byte 0 (Intel)

Floating-Point Representations

float, double, and long double data elements are represented according to the ANSI/ISO IEEE 754-1985 standard. The representation is:

(-1)s(e - bias)¥2 j.f

where:

The following tables show the position of the bits.

Table A-6 float Representation

Bits 

Name 

31 

Sign 

23 - 30 

Exponent 

0 - 22 

Fraction 

Table A-7 double Representation

Bits 

Name 

63 

Sign 

52 - 62 

Exponent 

0 - 51 

Fraction 

Table A-8 long double Representation (SPARC)

Bits 

Name 

127 

Sign 

112 - 126 

Exponent 

0 - 111 

Fraction 

Table A-9 long double Representation (Intel)

Bits 

Name 

80 - 95 

Unused 

79 

Sign 

64 - 78 

Exponent 

63 

Leading bit 

0 - 62 

Fraction 

For further information, refer to the Numerical Computation Guide.

Exceptional Values

float and double numbers are said to contain a "hidden," or implied, bit, providing for one more bit of precision than would otherwise be the case. In the case of long double, the leading bit is implicit (SPARC) or explicit (Intel); this bit is 1 for normal numbers, and 0 for subnormal numbers.

Table A-10 float Representations

normal number (0<e<255): 

(-1)Sign2 (exponent - 127)1.f

subnormal number (e=0, f!=0): 

(-1)Sign2 (-126)0.f

zero (e=0, f=0): 

(-1)Sign0.0

signaling NaN  

s=u, e=255(max); f=.0uuu-uu; at least one bit must be nonzero 

quiet NaN  

s=u, e=255(max); f=.1uuu-uu 

Infinity 

s=u, e=255(max); f=.0000-00 (all zeroes) 

Table A-11 double Representations

normal number (0<e<2047): 

(-1)Sign2 (exponent - 1023)1.f

subnormal number (e=0, f!=0): 

(-1)Sign2 (-1022)0.f

zero (e=0, f=0): 

(-1)Sign0.0

signaling NaN  

s=u, e=2047(max); f=.0uuu-uu; at least one bit must be nonzero 

quiet NaN  

s=u, e=2047(max); f=.1uuu-uu  

Infinity 

s=u, e=2047(max); f=.0000-00 (all zeroes)  

Table A-12 long double Representations

normal number (0<e<32767): 

(-1)Sign2 (exponent - 16383)1.f

subnormal number (e=0, f!=0): 

(-1)Sign2 (-16382)0.f

zero (e=0, f=0): 

(-1)Sign0.0

signaling NaN  

s=u, e=32767(max); f=.0uuu-uu; at least one bit must be nonzero 

quiet NaN  

s=u, e=32767(max); f=.1uuu-uu 

Infinity 

s=u, e=32767(max); f=.0000-00 (all zeroes)  

Hexadecimal Representation of Selected Numbers

The following tables show the hexadecimal representations.

Table A-13 Hexadecimal Representation of Selected Numbers (SPARC)

Value 

float

double

long double

+0 

-0 

00000000 

80000000 

0000000000000000 

8000000000000000 

00000000000000000000000000000000 

80000000000000000000000000000000 

+1.0 

-1.0 

3F800000 

BF800000 

3FF0000000000000  

BFF0000000000000  

3FFF00000000000000000000000000000 

BFFF00000000000000000000000000000 

+2.0 

+3.0 

40000000 

40400000 

4000000000000000 

4008000000000000  

40000000000000000000000000000000 

40080000000000000000000000000000 

+Infinity 

-Infinity 

7F800000 

FF800000 

7FF0000000000000  

FFF0000000000000  

7FFF00000000000000000000000000000 

FFFF00000000000000000000000000000 

NaN 

7FBFFFFF 

7FF7FFFFFFFFFFFF 

7FFF7FFFFFFFFFFFFFFFFFFFFFFFFFFF 

Table A-14 Hexadecimal Representation of Selected Numbers (Intel)

Value 

float

double

long double

+0 

-0 

00000000 

80000000 

0000000000000000 

0000000080000000 

00000000000000000000 

80000000000000000000 

+1.0 

-1.0 

3F800000 

BF800000 

000000003FF00000 

00000000BFF00000 

3FFF8000000000000000 

BFFF8000000000000000 

+2.0 

+3.0 

40000000 

40400000 

0000000040000000 

0000000040080000 

40008000000000000000 

4000C000000000000000 

+Infinity 

-Infinity 

7F800000 

FF800000 

000000007FF00000 

00000000FFF00000 

7FFF8000000000000000 

FFFF8000000000000000 

NaN 

7FBFFFFF 

FFFFFFFF7FF7FFFF 

7FFFBFFFFFFFFFFFFFFF 

For further information, refer to the Numerical Computation Guide.

Pointer Representation

A pointer in C occupies four bytes. The NULL value pointer is equal to zero.

Array Storage

Arrays are stored with their elements in a specific storage order. The elements are actually stored in a linear sequence of storage elements.

C arrays are stored in row-major order; the last subscript in a multidimensional array varies the fastest.

String data types are simply arrays of char elements.

Table A-15 Automatic Array Types and Storage

Type 

Maximum Number of Elements 

char

268435455 

short

134217727 

int

67108863 

long

67108863 

float

67108863 

double

33554431 

long double

1677215 (SPARC)

22369621 (Intel)

long long [Not valid in -Xc mode]

33554431 

Static and global arrays can accommodate many more elements.

Arithmetic Operations on Exceptional Values

This section describes the results derived from applying the basic arithmetic operations to combinations of exceptional and ordinary floating-point values. The information that follows assumes that no traps or any other exception actions are taken.

The following tables explain the abbreviations:

Table A-16 Abbreviation Usage

Abbreviation 

Meaning 

Num 

Subnormal or normal number  

Inf 

Infinity (positive or negative) 

NaN 

Not a number  

Uno 

Unordered 

The tables that follow describe the types of values that result from arithmetic operations performed with combinations of different types of operands.

Table A-17 Addition and Subtraction Results
 

 Right Operand  

Left Operand  

 0 

Num 

Inf 

NaN  

 0 

Num 

Inf 

NaN  

Num 

 Num 

See Note 

Inf 

NaN  

Inf 

 Inf 

Inf 

See Note 

NaN  

NaN 

 NaN 

NaN 

NaN 

NaN  


Note -

Num + Num could be Inf, rather than Num, when the result is too large (overflow). Inf + Inf = NaN when the infinities are of opposite sign.


Table A-18 Multiplication Results

 

 Right Operand  

Left Operand 

 0 

Num 

Inf 

NaN  

 0 

NaN 

NaN  

Num 

 0 

Num 

Inf 

NaN  

Inf 

 NaN 

Inf 

Inf 

NaN  

NaN 

 NaN 

NaN 

NaN 

NaN  

Table A-19 Division Results

 

 Right Operand  

Left Operand  

 0 

Num 

Inf 

NaN  

 NaN 

NaN  

Num 

 Inf 

Num 

NaN  

Inf 

 Inf 

Inf 

NaN 

NaN  

NaN 

 NaN 

NaN 

NaN 

NaN  

Table A-20 Comparison Results

 

 Right Operand  

Left Operand 

 0 

+Num 

+Inf 

NaN  

 = 

Uno  

+Num 

 > 

The result of the comparison 

Uno  

+Inf 

 > 

Uno  

NaN 

 Uno 

Uno 

Uno 

Uno  


Note -

NaN compared with NaN is unordered, and results in inequality. +0 compares equal to -0.


Argument-Passing Mechanism

This section describes how arguments are passed in ANSI/ISO C.

All arguments to C functions are passed by value.

Actual arguments are passed in the reverse order from which they are declared in a function declaration.

Actual arguments which are expressions are evaluated before the function reference. The result of the expression is then placed in a register or pushed onto the stack.

(SPARC)

Functions return integer results in register %o0, float results in register %f0, and double results in registers %f0 and %f1.

long long [Not available in -Xc mode.] integers are passed in registers with the higher word order in %oN, and the lower order word in %o(N+1). In-register results are returned in %i0 and %i1, with similar ordering.

All arguments, except doubles and long doubles, are passed as four-byte values. A double is passed as an eight-byte value. The first six four-byte values (double counts as 8) are passed in registers %o0 through %o5. The rest are passed onto the stack. Structures are passed by making a copy of the structure and passing a pointer to the copy. A long double is passed in the same manner as a structure.

Upon return from a function, it is the responsibility of the caller to pop arguments from the stack. Registers described are as seen by the caller.

(Intel)

Functions return integer results in register %eax.

long long results are returned in registers %edx and %eax. Functions return float, double, and long double results in register %st(0).

All arguments, except structs, unions, long longs, doubles and long doubles, are passed as four-byte values; a long long is passed as an eight-byte value, a double is passed as an eight-byte value, and a long double is passed as a 12-byte value.

structs and unions are copied onto the stack. The size is rounded up to a multiple of four bytes. Functions returning structs and unions are passed a hidden first argument, pointing to the location into which the returned struct or union is stored.

Upon return from a function, it is the responsibility of the caller to pop arguments from the stack, except for the extra argument for struct and union returns that is popped by the called function.