|
| 1 | +# Representation of Boolean, Floating Point, and Integral Types |
| 2 | +This chapter represents the consensus from issue [#9]. It documents the memory layout and considerations for `bool`, `usize`, `isize`, floating point types, and integral types. |
| 3 | +[#9]: https://github.com/rust-rfcs/unsafe-code-guidelines/issues/9 |
| 4 | + |
| 5 | +## Overview |
| 6 | +These are all scalar types, representing a single value. These types have no representation variants (no #[repr(C)] or #[repr(Rust)]. Their size is fixed and well-defined across FFI boundaries and map to their corresponding integral types in the C ABI. |
| 7 | +- `bool`: 1 byte |
| 8 | + - any `bool` can be cast into an integer, taking on the values 1 (true) or 0 (false) |
| 9 | +- `usize`, `isize`: pointer-sized unsigned/signed integer type |
| 10 | +- `u8` .. `u128`, `i8` .. `i128` |
| 11 | + - {8, 16, 32, 64, 128}-bit unsigned integer |
| 12 | + - {8, 16, 32, 64, 128}-bit signed integer |
| 13 | +- `f32`, `f64` |
| 14 | + - IEEE floats |
| 15 | + - 32-bit or 64-bit |
| 16 | +- `char` |
| 17 | + - C++ char: equivalent to either `i8`/`u8` |
| 18 | + - Rust char: 32-bit |
| 19 | + - not ABI compatible |
| 20 | + - represents [Unicode scalar value](http://www.unicode.org/glossary/#unicode_scalar_value) |
| 21 | + |
| 22 | +##`usize`/`isize` |
| 23 | +Types `usize` and `isize` are committed to having the same size as a native pointer on the platform. The representation of `usize` determines the following: |
| 24 | +- how much a pointer of a certain type can be offseted, |
| 25 | +- the maximum size of Rust objects (because size_of/size_of_val return `usize`), |
| 26 | +- the maximum number of elements in an array ([T; N: usize]), |
| 27 | +- `usize`/`isize` in C FFI are compatible with C's `uintptr_t` / `intptr_t` (and have the same size and alignment). |
| 28 | + |
| 29 | +The maximum size of any single value must fit within `usize` to [ensure that pointer diff is representable](https://github.com/rust-rfcs/unsafe-code-guidelines/pull/5#discussion_r212703192). |
| 30 | + |
| 31 | +`usize` and C’s `unsized` are *not* equivalent. |
| 32 | + |
| 33 | +## Booleans |
| 34 | +Rust's `bool` has the same layout as C17's` _Bool`, that is, its size and alignment are implementation-defined. |
| 35 | + |
| 36 | +Note: on all platforms that Rust's currently supports, the size and alignment of bool are 1, and its ABI class is INTEGER. |
| 37 | + |
| 38 | +For full ABI compatibility details, see [Gankro’s post] (https://gankro.github.io/blah/rust-layouts-and-abis/#the-layoutsabis-of-builtins). |
| 39 | + |
| 40 | +## Relationship to C integer hierarchy |
| 41 | +C integers: |
| 42 | +- char: at least 8 bits |
| 43 | +- short: at least 16 bits (also at least a char) |
| 44 | +- int: at least a short (intended to be a native integer size) |
| 45 | +- long: at least 32 bits (also at least an int) |
| 46 | +- long long: at least 64 bits (also at least a long) |
| 47 | +The C integer types specify a minimum size, but not the exact size. For this reason, Rust integer types are not necessarily compatible with the “corresponding” C integer type. Instead, use the corresponding fixed size data types (e.g. `i64` in Rust would correspond to `int64_t` in C). |
| 48 | + |
| 49 | +## Controversies |
| 50 | +There has been some debate about what to pick as the "official" behavior for bool: |
| 51 | +* Rust does what C does (this is what the lang team decided) |
| 52 | + * and in all cases you care about, that is 1 byte that is 0 or 1 |
| 53 | +or |
| 54 | +* Rust makes it 1 byte with values 0 or 1 |
| 55 | + * and in all cases you care about, this is what C does |
| 56 | + |
| 57 | +Related discussions: [document the size of bool](https://github.com/rust-lang/rust/pull/46156), [bool== _Bool?](https://github.com/rust-rfcs/unsafe-code-guidelines/issues/53#issuecomment-447050232), [bool ABI](https://github.com/rust-lang/rust/pull/46176#issuecomment-359593446) |
| 58 | + |
| 59 | + |
| 60 | + |
0 commit comments