[basic.types] (original) (raw)
6 Basics [basic]
[ Note
:
[basic.types] and the subclauses thereof impose requirements on implementations regarding the representation of types.
There are two kinds of types: fundamental types and compound types.
— end note
]
For any object (other than a potentially-overlapping subobject) of trivially copyable typeT, whether or not the object holds a valid value of typeT, the underlying bytes ([intro.memory]) making up the object can be copied into an array ofchar,unsigned char, orstd::byte ([cstddef.syn]).36
If the content of that array is copied back into the object, the object shall subsequently hold its original value.
[ Example
:
constexpr std::size_t N = sizeof(T);
char buf[N];
T obj;
std::memcpy(buf, &obj, N);
std::memcpy(&obj, buf, N);
— end example
]
For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neitherobj1 nor obj2 is a potentially-overlapping subobject, if the underlying bytes ([intro.memory]) making upobj1 are copied into obj2,37 obj2 shall subsequently hold the same value asobj1.
[ Example
:
T* t1p; T* t2p;
std::memcpy(t1p, t2p, sizeof(T));
— end example
]
The object representationof an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equalssizeof(T).
The value representationof an object of type T is the set of bits that participate in representing a value of type T.
Bits in the object representation that are not part of the value representation are padding bits.
For trivially copyable types, the value representation is a set of bits in the object representation that determines avalue, which is one discrete element of animplementation-defined set of values.38
A class that has been declared but not defined, an enumeration type in certain contexts ([dcl.enum]), or an array of unknown bound or of incomplete element type, is anincompletely-defined object type.39
Incompletely-defined object types and cv void areincomplete types ([basic.fundamental]).
Objects shall not be defined to have an incomplete type.
A class type (such as “class X”) might be incomplete at one point in a translation unit and complete later on; the type “class X” is the same type at both points.
The declared type of an array object might be an array of incomplete class type and therefore incomplete; if the class type is completed later on in the translation unit, the array type becomes complete; the array type at those two points is the same type.
The declared type of an array object might be an array of unknown bound and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (“array of unknown bound of T” and “array ofN T”) are different types.
The type of a pointer to array of unknown bound, or of a type defined by a typedef declaration to be an array of unknown bound, cannot be completed.
[ Example
:
class X;
extern X* xp;
extern int arr[];
typedef int UNKA[];
UNKA* arrp;
UNKA** arrpp;
void foo() {
xp++;
arrp++;
arrpp++;
}
struct X { int i; };
int arr[10];
X x;
void bar() {
xp = &x;
arrp = &arr;
xp++;
arrp++;
}
— end example
]
[ Note
:
The rules for declarations and expressions describe in which contexts incomplete types are prohibited.
— end note
]
An object type is a (possibly cv-qualified) type that is not a function type, not a reference type, and not cv void.
Arithmetic types ([basic.fundamental]), enumeration types, pointer types, pointer-to-member types ([basic.compound]),std::nullptr_t, andcv-qualified versions of these types are collectively calledscalar types.
Scalar types, trivially copyable class types ([class.prop]), arrays of such types, and cv-qualified versions of these types are collectively called trivially copyable types.
Scalar types, trivial class types ([class.prop]), arrays of such types and cv-qualified versions of these types are collectively calledtrivial types.
Scalar types, standard-layout class types ([class.prop]), arrays of such types and cv-qualified versions of these types are collectively called standard-layout types.
Scalar types, implicit-lifetime class types ([class.prop]), array types, and cv-qualified versions of these types are collectively called implicit-lifetime types.
A type is a literal type if it is:
- cv void; or
- a scalar type; or
- a reference type; or
- an array of literal type; or
- a possibly cv-qualified class type that has all of the following properties:
- it has a constexpr destructor ([dcl.constexpr]),
- it is either a closure type ([expr.prim.lambda.closure]), an aggregate type ([dcl.init.aggr]), or has at least one constexpr constructor or constructor template (possibly inherited from a base class) that is not a copy or move constructor,
- if it is a union, at least one of its non-static data members is of non-volatile literal type, and
- if it is not a union, all of its non-static data members and base classes are of non-volatile literal types.
[ Note
:
A literal type is one for which it might be possible to create an object within a constant expression.
It is not a guarantee that it is possible to create such an object, nor is it a guarantee that any object of that type will be usable in a constant expression.
— end note
]
6.8.1 Fundamental types [basic.fundamental]
There are five standard signed integer types :“signed char”, “short int”, “int”, “long int”, and “long long int”.
In this list, each type provides at least as much storage as those preceding it in the list.
There may also be implementation-definedextended signed integer types.
The standard and extended signed integer types are collectively calledsigned integer types.
The range of representable values for a signed integer type is to (inclusive), where N is called the width of the type.
[ Note
:
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.
— end note
]
For each of the standard signed integer types, there exists a corresponding (but different)standard unsigned integer type:“unsigned char”, “unsigned short int”, “unsigned int”, “unsigned long int”, and “unsigned long long int”.
Likewise, for each of the extended signed integer types, there exists a corresponding extended unsigned integer type.
The standard and extended unsigned integer types are collectively called unsigned integer types.
An unsigned integer type has the same width Nas the corresponding signed integer type.
The range of representable values for the unsigned type is0 to (inclusive); arithmetic for the unsigned type is performed modulo .
[ Note
:
Unsigned arithmetic does not overflow.
Overflow for signed arithmetic yields undefined behavior ([expr.pre]).
— end note
]
An unsigned integer type has the same object representation, value representation, and alignment requirements ([basic.align]) as the corresponding signed integer type.
For each value x of a signed integer type, the value of the corresponding unsigned integer type congruent to x modulo has the same value of corresponding bits in its value representation.40
[ Example
:
The value of a signed integer type has the same representation as the largest value of the corresponding unsigned type.
— end example
]
Table 12: Minimum width [tab:basic.fundamental.width]
| Type | Minimum width N |
|---|---|
| signed char | 8 |
| short | 16 |
| int | 16 |
| long | 32 |
| long long | 64 |
The width of each signed integer type shall not be less than the values specified in Table 12.
The value representation of a signed or unsigned integer type comprises N bits, where N is the respective width.
Each set of values for any padding bits ([basic.types]) in the object representation are alternative representations of the value specified by the value representation.
[ Note
:
Padding bits have unspecified value, but cannot cause traps.
In contrast, see ISO C 6.2.6.2.
— end note
]
[ Note
:
The signed and unsigned integer types satisfy the constraints given in ISO C 5.2.4.2.1.
— end note
]
Except as specified above, the width of a signed or unsigned integer type isimplementation-defined.
Each value x of an unsigned integer type with width N has a unique representation , where each coefficient is either 0 or 1; this is called the base-2 representation of x.
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.
The standard signed integer types and standard unsigned integer types are collectively called the standard integer types, and the extended signed integer types and extended unsigned integer types are collectively called theextended integer types.
A fundamental type specified to have a signed or unsigned integer type as its underlying type has the same object representation, value representation, alignment requirements ([basic.align]), and range of representable values as the underlying type.
Further, each value has the same representation in both types.
Type char is a distinct type that has an implementation-defined choice of “signed char” or “unsigned char” as its underlying type.
The values of type char can represent distinct codes for all members of the implementation's basic character set.
The three types char, signed char, and unsigned charare collectively calledordinary character types.
The ordinary character types and char8_tare collectively called narrow character types.
For narrow character types, each possible bit pattern of the object representation represents a distinct value.
[ Note
:
This requirement does not hold for other types.
— end note
]
[ Note
:
A bit-field of narrow character type whose width is larger than the width of that type has padding bits; see [basic.types].
— end note
]
Type wchar_t is a distinct type that has an implementation-defined signed or unsigned integer type as its underlying type.
The values of type wchar_t can represent distinct codes for all members of the largest extended character set specified among the supported locales ([locale]).
Type char8_t denotes a distinct type whose underlying type is unsigned char.
Types char16_t and char32_t denote distinct types whose underlying types are uint_least16_t and uint_least32_t, respectively, in <cstdint> ([cstdint.syn]).
Type bool is a distinct type that has the same object representation, value representation, and alignment requirements as an implementation-defined unsigned integer type.
The values of type bool aretrue and false.
[ Note
:
There are no signed, unsigned,short, or long bool types or values.
— end note
]
Typesbool,char, wchar_t,char8_t, char16_t, char32_t, and the signed and unsigned integer types are collectively calledintegral types.
A synonym for integral type is integer type.
[ Note
:
Enumerations ([dcl.enum]) are not integral; however, unscoped enumerations can be promoted to integral types as specified in [conv.prom].
— end note
]
There are three floating-point types:float,double, andlong double.
The type double provides at least as much precision as float, and the type long double provides at least as much precision as double.
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.
The value representation of floating-point types is implementation-defined.
[ Note
: This document imposes no requirements on the accuracy of floating-point operations; see also [support.limits]. — end note
]
Integral and floating-point types are collectively called arithmetic types.
Specializations of the standard library templatestd::numeric_limits shall specify the maximum and minimum values of each arithmetic type for an implementation.
A type cv voidis an incomplete type that cannot be completed; such a type has an empty set of values.
It is used as the return type for functions that do not return a value.
An expression of type cv void shall be used only as an expression statement, as an operand of a comma expression, as a second or third operand of ?: ([expr.cond]), as the operand oftypeid, noexcept, or decltype, as the expression in a return statement for a function with the return type cv void, or as the operand of an explicit conversion to type cv void.
Such values participate in the pointer and the pointer-to-member conversions ([conv.ptr], [conv.mem]).
sizeof(std::nullptr_t) shall be equal to sizeof(void*).
The types described in this subclause are called fundamental types.
[ Note
:
Even if the implementation defines two or more fundamental types to have the same value representation, they are nevertheless different types.
— end note
]
6.8.2 Compound types [basic.compound]
Compound types can be constructed in the following ways:
- arrays of objects of a given type, [dcl.array];
- functions, which have parameters of given types and returnvoid or references or objects of a given type, [dcl.fct];
- pointers to cv void or objects or functions (including static members of classes) of a given type, [dcl.ptr];
- references to objects or functions of a given type, [dcl.ref]. There are two types of references:
- lvalue reference
- rvalue reference
- classes containing a sequence of objects of various types ([class]), a set of types, enumerations and functions for manipulating these objects ([class.mfct]), and a set of restrictions on the access to these entities ([class.access]);
- unions, which are classes capable of containing objects of different types at different times, [class.union];
- enumerations, which comprise a set of named constant values. Each distinct enumeration constitutes a differentenumerated type, [dcl.enum];
- pointers to non-static class members,41which identify members of a given type within objects of a given class, [dcl.mptr]. Pointers to data members and pointers to member functions are collectively called pointer-to-member types.
These methods of constructing types can be applied recursively; restrictions are mentioned in [dcl.meaning].
Constructing a type such that the number of bytes in its object representation exceeds the maximum value representable in the type std::size_t ([support.types]) is ill-formed.
The type of a pointer to cv void or a pointer to an object type is called an object pointer type.
[ Note
:
A pointer to voiddoes not have a pointer-to-object type, however, because void is not an object type.
— end note
]
The type of a pointer that can designate a function is called a function pointer type.
A pointer to an object of type T is referred to as a “pointer toT”.
[ Example
:
A pointer to an object of type int is referred to as “pointer to int” and a pointer to an object of class X is called a “pointer to X”.
— end example
]
Except for pointers to static members, text referring to “pointers” does not apply to pointers to members.
Pointers to incomplete types are allowed although there are restrictions on what can be done with them ([basic.align]).
Every value of pointer type is one of the following:
- a pointer to an object or function (the pointer is said to point to the object or function), or
- a pointer past the end of an object ([expr.add]), or
- the null pointer value for that type, or
- an invalid pointer value.
A value of a pointer type that is a pointer to or past the end of an objectrepresents the address of the first byte in memory ([intro.memory]) occupied by the object42or the first byte in memory after the end of the storage occupied by the object, respectively.
[ Note
:
A pointer past the end of an object ([expr.add]) is not considered to point to an unrelated object of the object's type that might be located at that address.
A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see [basic.stc].
— end note
]
For purposes of pointer arithmetic ([expr.add]) and comparison ([expr.rel], [expr.eq]), a pointer past the end of the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical array element n of x and an object of type T that is not an array element is considered to belong to an array with one element of type T.
The value representation of pointer types is implementation-defined.
Pointers to layout-compatible types shall have the same value representation and alignment requirements ([basic.align]).
[ Note
:
Pointers to over-aligned types have no special representation, but their range of valid values is restricted by the extended alignment requirement.
— end note
]
Two objects a and b are pointer-interconvertible if:
- they are the same object, or
- one is a union object and the other is a non-static data member of that object ([class.union]), or
- one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, any base class subobject of that object ([class.mem]), or
- there exists an object c such thata and c are pointer-interconvertible, andc and b are pointer-interconvertible.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast.
[ Note
:
An array object and its first element are not pointer-interconvertible, even though they have the same address.
— end note
]
A pointer to cv voidcan be used to point to objects of unknown type.
Such a pointer shall be able to hold any object pointer.
An object of type cv void*shall have the same representation and alignment requirements as cv char*.
6.8.3 CV-qualifiers [basic.type.qualifier]
A type mentioned in [basic.fundamental] and [basic.compound] is a cv-unqualified type.
Each type which is a cv-unqualified complete or incomplete object type or isvoid ([basic.types]) has three corresponding cv-qualified versions of its type: a const-qualified version, avolatile-qualified version, and aconst-volatile-qualified version.
- A const object is an object of type const T or a non-mutable subobject of a const object.
- A volatile object is an object of typevolatile T or a subobject of a volatile object.
- A const volatile object is an object of typeconst volatile T, a non-mutable subobject of a const volatile object, a const subobject of a volatile object, or a non-mutable volatile subobject of a const object.
The cv-qualified or cv-unqualified versions of a type are distinct types; however, they shall have the same representation and alignment requirements ([basic.align]).43
Except for array types, a compound type ([basic.compound]) is not cv-qualified by the cv-qualifiers (if any) of the types from which it is compounded.
An array type whose elements are cv-qualified is also considered to have the same cv-qualifications as its elements.
[ Note
:
Cv-qualifiers applied to an array type attach to the underlying element type, so the notation “cv T”, where T is an array type, refers to an array whose elements are so-qualified ([dcl.array]).
— end note
]
[ Example
:
typedef char CA[5]; typedef const char CC; CC arr1[5] = { 0 }; const CA arr2 = { 0 };
The type of both arr1 and arr2 is “array of 5const char”, and the array type is considered to be const-qualified.
— end example
]
There is a partial ordering on cv-qualifiers, so that a type can be said to be more cv-qualified than another.
Table 13 shows the relations that constitute this ordering.
Table 13: Relations on const and volatile [tab:basic.type.qualifier.rel]
| no cv-qualifier | < | const |
|---|---|---|
| no cv-qualifier | < | volatile |
| no cv-qualifier | < | const volatile |
| const | < | const volatile |
| volatile | < | const volatile |
In this document, the notation cv (orcv1, cv2, etc.)
, used in the description of types, represents an arbitrary set of cv-qualifiers, i.e., one of {const}, {volatile}, {const,volatile}, or the empty set.
For a type cv T, the top-level cv-qualifiersof that type are those denoted by cv.
[ Example
:
The type corresponding to the type-id const int&has no top-level cv-qualifiers.
The type corresponding to the type-id volatile int * consthas the top-level cv-qualifier const.
For a class type C, the type corresponding to the type-id void (C::* volatile)(int) consthas the top-level cv-qualifier volatile.
— end example
]
6.8.4 Integer conversion rank [conv.rank]
Every integer type has an integer conversion rank defined as follows:
- No two signed integer types other than char and signed char (if char is signed) shall have the same rank, even if they have the same representation.
- The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller width.
- The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank ofshort int, which shall be greater than the rank ofsigned char.
- The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.
- The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
- The rank of char shall equal the rank of signed charand unsigned char.
- The rank of bool shall be less than the rank of all other standard integer types.
- The ranks of char8_t, char16_t, char32_t, andwchar_t shall equal the ranks of their underlying types ([basic.fundamental]).
- The rank of any extended signed integer type relative to another extended signed integer type with the same width is implementation-defined, but still subject to the other rules for determining the integer conversion rank.
- For all integer types T1, T2, and T3, ifT1 has greater rank than T2 and T2 has greater rank than T3, then T1 shall have greater rank thanT3.
[ Note
:
The integer conversion rank is used in the definition of the integral promotions ([conv.prom]) and the usual arithmetic conversions ([expr.arith.conv]).
— end note
]