[basic.fundamental] # 6 Basics [[basic]](./#basic) ## 6.9 Types [[basic.types]](basic.types#basic.fundamental) ### 6.9.2 Fundamental types [basic.fundamental] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5300) There are five [*standard signed integer types*](#def:type,standard_signed_integer "6.9.2 Fundamental types [basic.fundamental]"):“signed char”, “short int”, “int”, “long int”, and “long long int”[.](#1.sentence-1) In this list, each type provides at least as much storage as those preceding it in the list[.](#1.sentence-2) There may also be implementation-defined[*extended signed integer types*](#def:type,extended_signed_integer "6.9.2 Fundamental types [basic.fundamental]")[.](#1.sentence-3) The standard and extended signed integer types are collectively called[*signed integer types*](#def:type,signed_integer "6.9.2 Fundamental types [basic.fundamental]")[.](#1.sentence-4) The range of representable values for a signed integer type is−2N−1 to 2N−1−1 (inclusive), where N is called the [*width*](simd.general#def:width "29.10.1 General [simd.general]") of the type[.](#1.sentence-5) [*Note [1](#note-1)*: Plain ints are intended to have the natural width suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs[.](#1.sentence-6) — *end note*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5326) For each of the standard signed integer types, there exists a corresponding (but different)[*standard unsigned integer type*](#def:type,standard_unsigned_integer "6.9.2 Fundamental types [basic.fundamental]"):“unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”[.](#2.sentence-1) Likewise, for each of the extended signed integer types, there exists a corresponding [*extended unsigned integer type*](#def:type,extended_unsigned_integer "6.9.2 Fundamental types [basic.fundamental]")[.](#2.sentence-2) The standard and extended unsigned integer types are collectively called [*unsigned integer types*](#def:type,unsigned_integer "6.9.2 Fundamental types [basic.fundamental]")[.](#2.sentence-3) An unsigned integer type has the same width *N* as the corresponding signed integer type[.](#2.sentence-4) The range of representable values for the unsigned type is0 to 2N−1 (inclusive); arithmetic for the unsigned type is performed modulo 2N[.](#2.sentence-5) [*Note [2](#note-2)*: Unsigned arithmetic does not overflow[.](#2.sentence-6) Overflow for signed arithmetic yields undefined behavior ([[expr.pre]](expr.pre "7.1 Preamble"))[.](#2.sentence-7) — *end note*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5354) An unsigned integer type has the same object representation, value representation, and alignment requirements ([[basic.align]](basic.align "6.8.3 Alignment")) as the corresponding signed integer type[.](#3.sentence-1) For each value x of a signed integer type, the value of the corresponding unsigned integer type congruent to x modulo 2N has the same value of corresponding bits in its value representation[.](#3.sentence-2)[30](#footnote-30 "This is also known as two's complement representation.") [*Example [1](#example-1)*: The value −1 of a signed integer type has the same representation as the largest value of the corresponding unsigned type[.](#3.sentence-3) — *end example*] Table [14](#tab:basic.fundamental.width) — Minimum width [[tab:basic.fundamental.width]](./tab:basic.fundamental.width) | [🔗](#tab:basic.fundamental.width-row-1)
**Type** | **Minimum width N** | | --- | --- | | [🔗](#tab:basic.fundamental.width-row-2)
signed char | 8 | | [🔗](#tab:basic.fundamental.width-row-3)
short int | 16 | | [🔗](#tab:basic.fundamental.width-row-4)
int | 16 | | [🔗](#tab:basic.fundamental.width-row-5)
long int | 32 | | [🔗](#tab:basic.fundamental.width-row-6)
long long int | 64 | [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5385) The width of each standard signed integer type shall not be less than the values specified in Table [14](#tab:basic.fundamental.width "Table 14: Minimum width")[.](#4.sentence-1) The value representation of a signed or unsigned integer type comprises N bits, where N is the respective width[.](#4.sentence-2) Each set of values for any padding bits ([[basic.types.general]](basic.types.general "6.9.1 General")) in the object representation are alternative representations of the value specified by the value representation[.](#4.sentence-3) [*Note [3](#note-3)*: Padding bits have unspecified value, but cannot cause traps[.](#4.sentence-4) In contrast, see ISO/IEC 9899:2024 6.2.6.2[.](#4.sentence-5) — *end note*] [*Note [4](#note-4)*: The signed and unsigned integer types satisfy the constraints given in ISO/IEC 9899:2024 5.2.4.2.1[.](#4.sentence-6) — *end note*] Except as specified above, the width of a signed or unsigned integer type isimplementation-defined[.](#4.sentence-7) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5405) Each value x of an unsigned integer type with width N has a unique representation x=x020+x121+…+xN−12N−1, where each coefficient xi is either 0 or 1; this is called the [*base-2 representation*](#def:base-2_representation "6.9.2 Fundamental types [basic.fundamental]") of x[.](#5.sentence-1) The base-2 representation of a value of signed integer type is the base-2 representation of the congruent value of the corresponding unsigned integer type[.](#5.sentence-2) The standard signed integer types and standard unsigned integer types are collectively called the [*standard integer types*](#def:type,standard_integer "6.9.2 Fundamental types [basic.fundamental]"), and the extended signed integer types and extended unsigned integer types are collectively called the[*extended integer types*](#def:type,extended_integer "6.9.2 Fundamental types [basic.fundamental]")[.](#5.sentence-3) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5419) A fundamental type specified to have a signed or unsigned integer type as its [*underlying type*](#def:type,underlying "6.9.2 Fundamental types [basic.fundamental]") has the same object representation, value representation, alignment requirements ([[basic.align]](basic.align "6.8.3 Alignment")), and range of representable values as the underlying type[.](#6.sentence-1) Further, each value has the same representation in both types[.](#6.sentence-2) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5428) Type char is a distinct type that has an implementation-defined choice of “signed char” or “unsigned char” as its underlying type[.](#7.sentence-1) The three types char, signed char, and unsigned char are collectively called[*ordinary character types*](#def:type,ordinary_character "6.9.2 Fundamental types [basic.fundamental]")[.](#7.sentence-2) The ordinary character types and char8_t are collectively called [*narrow character types*](#def:type,narrow_character "6.9.2 Fundamental types [basic.fundamental]")[.](#7.sentence-3) For narrow character types, each possible bit pattern of the object representation represents a distinct value[.](#7.sentence-4) [*Note [5](#note-5)*: This requirement does not hold for other types[.](#7.sentence-5) — *end note*] [*Note [6](#note-6)*: A bit-field of narrow character type whose width is larger than the width of that type has padding bits; see [[basic.types.general]](basic.types.general "6.9.1 General")[.](#7.sentence-6) — *end note*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5454) Type wchar_t is a distinct type that has an implementation-defined signed or unsigned integer type as its underlying type[.](#8.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5462) Type char8_t denotes a distinct type whose underlying type is unsigned char[.](#9.sentence-1) Types char16_t and char32_t denote distinct types whose underlying types are uint_least16_t and uint_least32_t, respectively, in [](cstdint.syn#header:%3ccstdint%3e "17.4.1 Header synopsis [cstdint.syn]")[.](#9.sentence-2) [10](#10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5478) Type bool is a distinct type that has the same object representation, value representation, and alignment requirements as an implementation-defined unsigned integer type[.](#10.sentence-1) The values of type bool aretrue and false[.](#10.sentence-2) [*Note [7](#note-7)*: There are no signed, unsigned,short, or long bool types or values[.](#10.sentence-3) — *end note*] [11](#11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5493) The types char, wchar_t,char8_t, char16_t, and char32_t are collectively called [*character types*](#def:type,character "6.9.2 Fundamental types [basic.fundamental]")[.](#11.sentence-1) The character types, bool, the signed and unsigned integer types, and cv-qualified versions ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) thereof, are collectively termed[*integral types*](#def:integral_type "6.9.2 Fundamental types [basic.fundamental]")[.](#11.sentence-2) A synonym for integral type is [*integer type*](#def:integer_type "6.9.2 Fundamental types [basic.fundamental]")[.](#11.sentence-3) [*Note [8](#note-8)*: Enumerations ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")) are not integral; however, unscoped enumerations can be promoted to integral types as specified in [[conv.prom]](conv.prom "7.3.7 Integral promotions")[.](#11.sentence-4) — *end note*] [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5510) The three distinct typesfloat,double, andlong double can represent floating-point numbers[.](#12.sentence-1) The type double provides at least as much precision as float, and the type long double provides at least as much precision as double[.](#12.sentence-2) The set of values of the typefloat is a subset of the set of values of the typedouble; the set of values of the type double is a subset of the set of values of the type long double[.](#12.sentence-3) The typesfloat, double, and long double, and cv-qualified versions ([[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")) thereof, are collectively termed[*standard floating-point types*](#def:type,floating-point,standard "6.9.2 Fundamental types [basic.fundamental]")[.](#12.sentence-4) An implementation may also provide additional types that represent floating-point values and define them (and cv-qualified versions thereof) to be[*extended floating-point types*](#def:type,floating-point,extended "6.9.2 Fundamental types [basic.fundamental]")[.](#12.sentence-5) The standard and extended floating-point types are collectively termed [*floating-point types*](#def:type,floating-point "6.9.2 Fundamental types [basic.fundamental]")[.](#12.sentence-6) [*Note [9](#note-9)*: Any additional implementation-specific types representing floating-point values that are not defined by the implementation to be extended floating-point types are not considered to be floating-point types, and this document imposes no requirements on them or their interactions with floating-point types[.](#12.sentence-7) — *end note*] Except as specified in [[basic.extended.fp]](basic.extended.fp "6.9.3 Optional extended floating-point types"), the object and value representations and accuracy of operations of floating-point types are implementation-defined[.](#12.sentence-8) [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5548) The minimum range of representable values for a floating-point type is the most negative finite floating-point number representable in that type through the most positive finite floating-point number representable in that type[.](#13.sentence-1) In addition, if negative infinity is representable in a type, the range of that type is extended to all negative real numbers; likewise, if positive infinity is representable in a type, the range of that type is extended to all positive real numbers[.](#13.sentence-2) [*Note [10](#note-10)*: Since negative and positive infinity are representable in ISO/IEC 60559 formats, all real numbers lie within the range of representable values of a floating-point type adhering to ISO/IEC 60559[.](#13.sentence-3) — *end note*] [14](#14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5564) Integral and floating-point types are collectively termed [*arithmetic types*](#def:type,arithmetic "6.9.2 Fundamental types [basic.fundamental]")[.](#14.sentence-1) [*Note [11](#note-11)*: Properties of the arithmetic types, such as their minimum and maximum representable value, can be queried using the facilities in the standard library headers[](limits.syn#header:%3climits%3e "17.3.3 Header synopsis [limits.syn]"),[](climits.syn#header:%3cclimits%3e "17.3.6 Header synopsis [climits.syn]"), and[](cfloat.syn#header:%3ccfloat%3e "17.3.7 Header synopsis [cfloat.syn]")[.](#14.sentence-2) — *end note*] [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5576) A type cv void is an incomplete type that cannot be completed; such a type has an empty set of values[.](#15.sentence-1) It is used as the return type for functions that do not return a value[.](#15.sentence-2) An expression of type cv void shall be used only as - [(15.1)](#15.1) an expression statement ([[stmt.expr]](stmt.expr "8.3 Expression statement")), - [(15.2)](#15.2) the expression in a return statement ([[stmt.return]](stmt.return "8.8.4 The return statement")) for a function with the return type cv void, - [(15.3)](#15.3) an operand of a comma expression ([[expr.comma]](expr.comma "7.6.20 Comma operator")), - [(15.4)](#15.4) the second or third operand of ?: ([[expr.cond]](expr.cond "7.6.16 Conditional operator")), - [(15.5)](#15.5) the operand of a typeid expression ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")), - [(15.6)](#15.6) the operand of a noexcept operator ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator")), - [(15.7)](#15.7) the operand of a decltype specifier ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")), or - [(15.8)](#15.8) the operand of an explicit conversion to typecv void ([[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9 Static cast"), [[expr.cast]](expr.cast "7.6.3 Explicit type conversion (cast notation)"))[.](#15.sentence-3) [16](#16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5597) The types denoted by cv std​::​nullptr_t are distinct types[.](#16.sentence-1) A prvalue of type std​::​nullptr_t is a null pointer constant ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions"))[.](#16.sentence-2) Such values participate in the pointer and the pointer-to-member conversions ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions"), [[conv.mem]](conv.mem "7.3.13 Pointer-to-member conversions"))[.](#16.sentence-3) sizeof(std​::​nullptr_t) shall be equal to sizeof(void*)[.](#16.sentence-4) [17](#17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5604) A value of type std​::​meta​::​info is called a [*reflection*](#def:reflection "6.9.2 Fundamental types [basic.fundamental]")[.](#17.sentence-1) There exists a unique [*null reflection*](#def:reflection,null "6.9.2 Fundamental types [basic.fundamental]"); every other reflection is a representation of - [(17.1)](#17.1) a value of scalar type ([[temp.param]](temp.param "13.2 Template parameters")), - [(17.2)](#17.2) an object with static storage duration ([[basic.stc]](basic.stc "6.8.6 Storage duration")), - [(17.3)](#17.3) a variable ([[basic.pre]](basic.pre "6.1 Preamble")), - [(17.4)](#17.4) a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")), - [(17.5)](#17.5) a function ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), - [(17.6)](#17.6) a function parameter, - [(17.7)](#17.7) an enumerator ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")), - [(17.8)](#17.8) an annotation ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics")), - [(17.9)](#17.9) a type alias ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")), - [(17.10)](#17.10) a type ([[basic.types]](basic.types "6.9 Types")), - [(17.11)](#17.11) a class member ([[class.mem]](class.mem "11.4 Class members")), - [(17.12)](#17.12) an unnamed bit-field ([[class.bit]](class.bit "11.4.10 Bit-fields")), - [(17.13)](#17.13) a class template ([[temp.pre]](temp.pre "13.1 Preamble")), - [(17.14)](#17.14) a function template, - [(17.15)](#17.15) a variable template, - [(17.16)](#17.16) an alias template ([[temp.alias]](temp.alias "13.7.8 Alias templates")), - [(17.17)](#17.17) a concept ([[temp.concept]](temp.concept "13.7.9 Concept definitions")), - [(17.18)](#17.18) a namespace alias ([[namespace.alias]](namespace.alias "9.9.3 Namespace alias")), - [(17.19)](#17.19) a namespace ([[basic.namespace.general]](basic.namespace.general "9.9.1 General")), - [(17.20)](#17.20) a direct base class relationship ([[class.derived.general]](class.derived.general "11.7.1 General")), or - [(17.21)](#17.21) a data member description ([[class.mem.general]](class.mem.general "11.4.1 General"))[.](#17.sentence-2) A reflection is said to [*represent*](#def:represent "6.9.2 Fundamental types [basic.fundamental]") the corresponding construct[.](#17.sentence-3) [*Note [12](#note-12)*: A reflection of a value can be produced by library functions such asstd​::​meta​::​constant_of and std​::​meta​::​reflect_constant[.](#17.sentence-4) — *end note*] [*Example [2](#example-2)*: int arr[] = {1, 2, 3};auto [a1, a2, a3] = arr;void fn();enum Enum { A };using Alias = int;struct B {};struct S : B {int mem; int : 0;};template struct TCls {};template void TFn();template int TVar;template concept Concept = requires { true; };namespace NS {};namespace NSAlias = NS; constexpr auto ctx = std::meta::access_context::current(); constexpr auto r1 = std::meta::reflect_constant(42); // represents int value of 42constexpr auto r2 = std::meta::reflect_object(arr[1]); // represents int objectconstexpr auto r3 = ^^arr; // represents a variableconstexpr auto r4 = ^^a3; // represents a structured bindingconstexpr auto r5 = ^^fn; // represents a functionconstexpr auto r6 = ^^Enum::A; // represents an enumeratorconstexpr auto r7 = ^^Alias; // represents a type aliasconstexpr auto r8 = ^^S; // represents a typeconstexpr auto r9 = ^^S::mem; // represents a class memberconstexpr auto r10 = std::meta::members_of(^^S, ctx)[1]; // represents an unnamed bit-fieldconstexpr auto r11 = ^^TCls; // represents a class templateconstexpr auto r12 = ^^TFn; // represents a function templateconstexpr auto r13 = ^^TVar; // represents a variable templateconstexpr auto r14 = ^^Concept; // represents a conceptconstexpr auto r15 = ^^NSAlias; // represents a namespace aliasconstexpr auto r16 = ^^NS; // represents a namespaceconstexpr auto r17 = std::meta::bases_of(^^S, ctx)[0]; // represents a direct base class relationshipconstexpr auto r18 = std::meta::data_member_spec(^^int, {.name="member"}); // represents a data member description — *end example*] [18](#18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5679) *Recommended practice*: Implementations should not represent other constructs specified in this document, such as[*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")*s*, partial template specializations, attributes, placeholder types, statements, or expressions, as values of type std​::​meta​::​info[.](#18.sentence-1) [*Note [13](#note-13)*: Future revisions of this document can specify semantics for reflections representing any such constructs[.](#18.sentence-2) — *end note*] [19](#19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5694) The types described in this subclause are called [*fundamental types*](#def:fundamental_type "6.9.2 Fundamental types [basic.fundamental]")[.](#19.sentence-1) [*Note [14](#note-14)*: Even if the implementation defines two or more fundamental types to have the same value representation, they are nevertheless different types[.](#19.sentence-2) — *end note*] [30)](#footnote-30)[30)](#footnoteref-30) This is also known as two's complement representation[.](#footnote-30.sentence-1)