4.1. C/C++ type details
4.1.1. C/C++ type sizes and alignments
There are two conventions for C/C++ type sizes and alignments.
- ILP32, ILP32F, ILP32D, and ILP32E
-
Use the following type sizes and alignments (based on the ILP32 convention):
Table 1. C/C++ type sizes and alignments for RV32 Type Size (Bytes) Alignment (Bytes) bool/_Bool
1
1
char
1
1
short
2
2
int
4
4
long
4
4
long long
8
8
void *
4
4
_Float16
2
2
float
4
4
double
8
8
long double
16
16
float _Complex
8
4
double _Complex
16
8
long double _Complex
32
16
- LP64, LP64F, LP64D, and LP64Q
-
Use the following type sizes and alignments (based on the LP64 convention):
Table 2. C/C++ type sizes and alignments for RV64 Type Size (Bytes) Alignment (Bytes) bool/_Bool
1
1
char
1
1
short
2
2
int
4
4
long
8
8
long long
8
8
__int128
16
16
void *
8
8
_Float16
2
2
float
4
4
double
8
8
long double
16
16
float _Complex
8
4
double _Complex
16
8
long double _Complex
32
16
The alignment of max_align_t is 16.
CHAR_BIT is 8.
Structs and unions are aligned to the alignment of their most strictly aligned member. The size of any object is a multiple of its alignment.
4.1.2. C/C++ type representations
char is unsigned.
Booleans (bool/_Bool) stored in memory or when being passed as scalar
arguments are either 0 (false) or 1 (true).
A null pointer (for all types) has the value zero.
_Float16 is as defined in the C ISO/IEC TS 18661-3 extension.
_Complex types have the same layout as a struct containing two fields of the
corresponding real type (float, double, or long double), with the first
member holding the real part and the second member holding the imaginary part.
4.1.3. va_list, va_start, and va_arg
The va_list type is void*. A callee with variadic arguments is responsible
for copying the contents of registers used to pass variadic arguments to the
vararg save area, which must be contiguous with arguments passed on the stack.
The va_start macro initializes its va_list argument to point to the start
of the vararg save area. The va_arg macro will increment its va_list
argument according to the size of the given type, taking into account the
rules about 2×XLEN aligned arguments being passed in "aligned" register pairs.