This appendix describes how ISO 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 with C code.
The following table shows the data types and how they are represented.
Storage allocated on the stack (identifiers with internal, or automatic, linkage) should be limited to two gigabytes or less.
Bit numbering of any given data element depend on the architecture in use: SPARCstationTM 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 types used in ISO C are short, int, long, and long long:
Table F–2 Representation of short
Bits |
Content |
---|---|
8- 15 |
Byte 0 (SPARC) Byte 1 (x86) |
0- 7 |
Byte 1 (SPARC) Byte 0 (x86) |
Table F–3 Representation of int
Bits |
Content |
---|---|
24- 31 |
Byte 0 (SPARC) Byte 3 (x86) |
16- 23 |
Byte 1 (SPARC) Byte 2 (x86) |
8- 15 |
Byte 2 (SPARC) Byte 1 (x86) |
0- 7 |
Byte 3 (SPARC) Byte 0 (x86) |
Table F–4 Representation of long on x86 and SPARC v8 versus SPARC v9
Bits |
Content |
---|---|
24- 31 |
Byte 0 (SPARC) v8 Byte 4 (SPARC) v9 Byte 3 (x86) |
16- 23 |
Byte 1 (SPARC) v8 Byte 5 (SPARC) v9 Byte 2 (x86) |
8- 15 |
Byte 2 (SPARC) v8 Byte 6 (SPARC) v9 Byte 1 (x86) |
0- 7 |
Byte 3 (SPARC) v8 Byte 7 (SPARC) v9 Byte 0 (x86) |
long long is not available in -Xc mode.
Bits |
Content |
---|---|
56- 63 |
Byte 0 (SPARC) Byte 7 (x86) |
48- 55 |
Byte 1 (SPARC) Byte 6 (x86) |
40- 47 |
Byte 2 (SPARC) Byte 5 (x86) |
32- 39 |
Byte 3 (SPARC) Byte 4 (x86) |
24- 31 |
Byte 4 (SPARC) Byte 3 (x86) |
16- 23 |
Byte 5 (SPARC) Byte 2 (x86) |
8- 15 |
Byte 6 (SPARC) Byte 1 (x86) |
0- 7 |
Byte 7 (SPARC) Byte 0 (x86) |
float, double, and long double data elements are represented according to the ISO IEEE 754-1985 standard. The representation is:
(-1)s(e- bias)¥2 j.f
where:
s = sign
e = biased exponent
j is the leading bit, determined by the value of e. In the case of long double (x86), the leading bit is explicit; in all other cases, it is implicit.
f = fraction
u means that the bit can be either 0 or 1.
The following tables show the position of the bits.
Table F–6 float Representation
Bits |
Name |
---|---|
31 |
Sign |
23- 30 |
Exponent |
0- 22 |
Fraction |
Table F–7 double Representation
Bits |
Name |
---|---|
63 |
Sign |
52- 62 |
Exponent |
0- 51 |
Fraction |
Table F–8 long double Representation (SPARC)
Bits |
Name |
---|---|
127 |
Sign |
112- 126 |
Exponent |
0- 111 |
Fraction |
Table F–9 long double Representation (x86)
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.
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 (x86); this bit is 1 for normal numbers, and 0 for subnormal numbers.
Table F–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 F–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 F–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) |
The following tables show the hexadecimal representations.
Table F–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 F–14 Hexadecimal Representation of Selected Numbers (x86)
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.
A pointer in C occupies four bytes. A pointer in C occupies eight bytes on SPARC v9 architectures. The NULL value pointer is equal to zero.
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. The maximum number of characters allowed in a string literal or wide string literal (after concatenation) is 4,294,967,295.
See F.1 Storage Allocation for information on the size limit of storage allocated on the stack.
Table F–15 Array Types and Storage
Type |
Maximum Number of Elements for SPARC and x86 |
Maximum Number of Elements for SPARC V9 |
---|---|---|
char |
4,294,967,295 |
2,305,843,009,213,693,951 |
short |
2,147,483,647 |
1,152,921,504,606,846,975 |
int |
1,073,741,823 |
576,460,752,303,423,487 |
long |
1,073,741,823 |
288,230,376,151,711,743 |
float |
1,073,741,823 |
576,460,752,303,423,487 |
double |
536,870,911 |
288,230,376,151,711,743 |
long double |
268,435,451 |
144,115,188,075,855,871 |
536,870,911 |
288,230,376,151,711,743 |
Static and global arrays can accommodate many more elements.
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 table explains the abbreviations:
Table F–16 Abbreviation Usage
Abbreviation |
Meaning |
---|---|
Num |
Subnormal or normal number |
Inf |
Infinity (positive or negative) |
NaN |
Not a number |
Uno |
Unordered |
The following tables describe the types of values that result from arithmetic operations performed with combinations of different types of operands.
Table F–17 Addition and Subtraction ResultsTable F–18 Multiplication Results
|
Right Operand:0 |
Right Operand:Num |
Right Operand:Inf |
Right Operand:NaN |
---|---|---|---|---|
Left Operand:0 |
0 |
0 |
NaN |
NaN |
Left Operand: Num |
0 |
Num |
Inf |
NaN |
Left Operand: Inf |
NaN |
Inf |
Inf |
NaN |
Left Operand: NaN |
NaN |
NaN |
NaN |
NaN |
Table F–19 Division Results
|
Right Operand:0 |
Right Operand:Num |
Right Operand:Inf |
Right Operand:NaN |
---|---|---|---|---|
Left Operand:0 |
NaN |
0 |
0 |
NaN |
Left Operand: Num |
Inf |
Num |
0 |
NaN |
Left Operand: Inf |
Inf |
Inf |
NaN |
NaN |
Left Operand: NaN |
NaN |
NaN |
NaN |
NaN |
Table F–20 Comparison Results
|
Right Operand:0 |
Right Operand:+Num |
Right Operand:+Inf |
Right Operand:+NaN |
---|---|---|---|---|
Left Operand:0 |
= |
< |
< |
Uno |
Left Operand: +Num |
> |
The result of the comparison |
< |
Uno |
Left Operand: +Inf |
> |
> |
= |
Uno |
Left Operand: +NaN |
Uno |
Uno |
Uno |
Uno |
NaN compared with NaN is unordered, and results in inequality. +0 compares equal to- 0.
This section describes how arguments are passed in 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.
Functions return integer results in register %o0, float results in register %f0, and double results in registers %f0 and %f1.
long long 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 %o0 and %o1, 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.
Registers described are as seen by the caller.
All integral arguments are passed as eight-byte values.
Floating-point arguments are passed in floating-point registers when possible.
Functions return results in the following registers:
Table F–21 Registers Used by x86 Functions to Return Types
Register |
Type Returned |
---|---|
int |
%eax |
%edx and %eax |
|
float, double, and long double |
%st(0) |
float _Complex |
%eax for the real part and %edx for the imaginary part |
double _Complex and long double _Complex |
The same as a struct that contains two elements of the corresponding floating point type. |
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.