ISO/IEC JTC1 SC22 WG21 P1236R1
Jens Maurer <Jens.Maurer@gmx.net>
Target audience: CWG
2018-11-09
The wording presented here also resolved the following core issues:
There are further cleanups in the area of integer types beyond requiring two's complement notation, not all of which Jean François Bastien may agree with.
The semantics of bitwise operators are reformulated based on the base-2 representation of the operand values.
Bit-fields now consistently use the term "width" (instead of "length").
As per EWG decision in San Diego, deviating from P0907R3, bool is specified to have some integral type as its underlying type, but the presence of padding bits for "bool" will remain unspecified, as will the mapping of true and false to values of the underlying type.unsigned char is i.
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-defined extended signed
integer types. The standard and extended signed integer types are
collectively called signed integer types.
The range of representable values for a signed integer type is
-2N-1 to 2N-1-1 (inclusive),
where N is called the range exponent of the type.
[ Note: Plain ints have the natural size
suggested by the architecture of the execution environment
[ Footnote: ;
the other signed integer types are provided to meet special needs.
-- end note ]
int must also be large enough to contain any
value in the range [INT_MIN, INT_MAX], as defined in the header
<climits>. ]
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 range exponent N as the corresponding signed integer type. The range of representable values for the unsigned type is 0 to 2N-1 (inclusive); arithmetic for the unsigned type is performed modulo 2N. [ Note: Unsigned arithmetic does not overflow. Overflow for signed arithmetic yields undefined behavior (7.1 [expr.pre]). -- end note ]
An unsigned integer type
, each of which occupies the same amount of storage and has the same
object representation, value representation, and
alignment requirements (6.6.5 [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
2N has
the same value of corresponding bits in its value
representation. [ Footnote: This is also known as two's
complement representation. ] [ Example: The value -1 of a signed
integer type has the same representation as the largest value
of the corresponding
unsigned type. ]
The range exponent of each signed integer type shall not be less than the values specified in table X.
| type | minimum range exponent N |
|---|---|
signed char | 8 |
short | 16 |
int | 16 |
long | 32 |
long long | 64 |
The range of non-negative values of a signed
integer type is a subrange of the corresponding unsigned integer type,
the representation of the same value in each of the two types is the
same, and the value representation of each corresponding
signed/unsigned type shall be the same.
Each value x of an unsigned integer type with range exponent N has a unique representation x = x0 20 + x1 21 + ... + xN-1 2N-1, where each coefficient xi 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 the extended integer types. The signed and
unsigned integer types shall satisfy the constraints given in the C
standard, subclause 5.2.4.2.1.
Unsigned integers shall obey the laws of arithmetic modulo
2n where n is the number of bits in the value
representation of that particular size of integer. [ Footnote: This
implies that unsigned arithmetic does not overflow because a result
that cannot be represented by the resulting unsigned integer type is
reduced modulo the number that is one greater than the largest value
that can be represented by the resulting unsigned integer type. ]
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 (6.6.5 [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
char are 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
range exponent of that type has padding bits; see 6.7
[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
whose values can
represent distinct codes for all members of the largest extended
character set specified among the supported locales (26.3.1
[locale]). Type Types wchar_t shall have the same size,
signedness, and alignment requirements (6.6.5 [basic.align]) as one of
the other integral types, called its
underlying type.char16_t and char32_t
denote distinct types with the same size, signedness, and
alignment as whose underlying types are
uint_least16_t and uint_least32_t,
respectively, in <cstdint>, called the underlying types.
Type bool is a distinct type that has the
same object representation, value representation, and alignment requirements as
an implementation-defined unsigned integer type.
Values The values of type bool are either true or and false.
[ Footnote: Using a bool
value in ways described by this document as "undefined", such as by
examining the value of an uninitialized automatic object, might cause
it to behave as if it is neither true nor false. ] [Note: There are
no signed, unsigned, short, or long bool types or values. -- end note]
Values of type
bool participate in integral promotions
(7.3.6 [conv.prom]).
bool, char, char16_t,
char32_t, wchar_t, and the signed and
unsigned integer types are collectively called
integral types.
If the destination type is signed, the value is unchanged if it can be
represented in the destination type; otherwise, the value is
implementation-defined.
If the destination type is bool, see 7.3.14
[conv.bool]. If the source type is bool, the value false
is converted to zero and the value true is converted to one.
A value of a scoped enumeration type (9.6) can be explicitly converted to an integral typeChange in 7.6.7 [expr.shift] paragraphs 1-4: The shift operators << and >> group left-to-right.. When that type is cv bool, the resulting value is false if the original value is zero and true for all other values. For the remaining integral types, the value is unchanged if the original value can be represented by the specified type. Otherwise, the resulting value is unspecified; the result is the same as that of converting to the enumeration's underlying type and then to the destination type. A value of a scoped enumeration type can also be explicitly converted to a floating-point type; the result is the same as that of converting from the original value to the floating-point type.
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The
type of the result is that of the promoted left operand. The behavior is undefined if the right operand is
negative, or greater than or equal to the
The value of E1 << E2 is the unique value congruent to
E1 x 2E2 modulo 2N, where N is the range
exponent of the type of the result.
[ Note:
E1 is left-shifted E2 bit positions; vacated
bits are zero-filled. -- end note ] If E1 has an
unsigned type, the value of the result is E1 x 2E2, reduced
modulo one more than the maximum value representable in the result
type. Otherwise, if E1 has a signed type and non-negative value, and
E1 x 2E2 is representable in the corresponding unsigned
type of the result type, then that value, converted to the result
type, is the resulting value; otherwise, the behavior is
undefined.
The value of E1 >> E2 is E1 / 2E2, rounded down.
[ Note: E1 is right-shifted E2 bit positions.
Right-shift on signed integral types is an arithmetic right
shift, which performs sign-extension. - end note ]
If E1 has an unsigned type or if E1 has a signed type and a
non-negative value, the value of the result is the integral part of
the quotient of E1/2E2. If E1 has a signed type and a negative value,
the resulting value is implementation-defined.
Change in 7.6.12 [expr.bit.xor]:and-expression: equality-expression and-expression & equality-expressionThe operands shall be of integral or unscoped enumeration type. The usual arithmetic conversions (7.4 [expr.arith.conv]) are performed. Given the coefficients xi and yi of the base-2 representation (6.7.1 [basic.fundamental]) of the converted operands x and y, the coefficient ri of the base-2 representation of the result r is 1 if both xi and yi are 1, and 0 otherwise. [ Note: The; theresult is the bitwise AND function of the operands. -- end note]The operator applies only to integral or unscoped enumeration operands.
Change in 7.6.13 [expr.or]:exclusive-or-expression: and-expression exclusive-or-expression ^ and-expressionThe operands shall be of integral or unscoped enumeration type. The usual arithmetic conversions (7.4 [expr.arith.conv]) are performed. Given the coefficients xi and yi of the base-2 representation (6.7.1 [basic.fundamental]) of the converted operands x and y, the coefficient ri of the base-2 representation of the result r is 1 if either (but not both) of xi and yi are 1, and 0 otherwise. [ Note: The; theresult is the bitwise exclusive OR function of the operands. -- end note]The operator applies only to integral or unscoped enumeration operands.
Change in 9.6 [dcl.enum] paragraph 8:inclusive-or-expression: exclusive-or-expression inclusive-or-expression | exclusive-or-expressionThe operands shall be of integral or unscoped enumeration type. The usual arithmetic conversions (7.4 [expr.arith.conv]) are performed. Given the coefficients xi and yi of the base-2 representation (6.7.1 [basic.fundamental]) of the converted operands x and y, the coefficient ri of the base-2 representation of the result r is 1 if at least one of xi and yi is 1, and 0 otherwise. [ Note: The; theresult is the bitwise inclusive OR function of its operands. -- end note]The operator applies only to integral or unscoped enumeration operands.
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise,Change in 10.3.10 [class.bit] paragraph 1-4: A member-declarator of the formfor an enumeration where emin is the smallest enumerator and emax is the largest,the values of the enumeration are the values representable by a hypothetical integer types with minimal range exponent M such that all enumerators can be represented.in the range bmin to bmax, defined as follows:TheLet K be 1 for a two's complement representation and 0 for a ones' complement or sign-magnitude representation.bmax is the smallest value greater than or equal to max(|emin | - K, |emax |) and equal to 2M - 1, where M is a non-negative integer. bmin is zero if emin is non-negative and -(bmax + K) otherwise.sizewidth of the smallest bit-field large enough to hold all the values of the enumeration type is Mmax(M, 1) if bmin is zero and M + 1 otherwise. It is possible to define an enumeration that has values not defined by any of its enumerators. If the enumerator-list is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0. [ Footnote: ... ]
identifieropt attribute-specifier-seqopt : constant-expression brace-or-equal-initializeroptspecifies a bit-field
A declaration for a bit-field that omits the identifier declares an
unnamed bit-field. Unnamed bit-fields are not members and
cannot be initialized. An unnamed bit-field shall not be declared with
a cv-qualified type. [Note: An unnamed bit-field is useful for
padding to conform to externally-imposed layouts. -- end note] As a
special case, an unnamed bit-field with a width of zero specifies
alignment of the next bit-field at an allocation unit boundary. Only
when declaring an unnamed bit-field may the value of the
constant-expression width be equal to zero.
A bit-field shall not be a static member. A bit-field shall have
integral or enumeration type (6.7.1). A The
address-of operator & shall not be applied to a bit-field, so there
are no pointers to bit-fields. A non-const reference shall not be
bound to a bit-field (9.3.3). [Note: If the initializer for a
reference of type const T& is an lvalue that refers to a bit-field,
the reference is bound to a temporary initialized to hold the value of
the bit-field; the reference is not bound to the bit-field
directly. See 9.3.3. -- end note]
bool value
can successfully be stored in a bit-field of any nonzero size.
bool) is
stored into a bit-field of width N and the value would be
representable in a hypothetical signed or unsigned integer type with
range exponent N and the same signedness as the bit-field's
type, the original value and the value of the bit-field
compare equal.
If the value true or false is stored
into a bit-field of type bool of any size
(including a one bit bit-field), the original bool value
and the value of the bit-field
... The set of scalar types for which this condition holds is implementation-defined. [Note: If a type has padding bits, the condition does not hold; otherwise, the condition holds true forChange in 19.16.3 [ratio.ratio] paragraph 1:unsignedintegral types. -- end note]
If the template argument D is zero or the absolute values of either of the template arguments N and D is no representable by typeChange in 29.6.2 [atomics.ref.int] paragraph 6:intmax_t, the program is ill-formed. [Note: These rules ensure that infinite ratios are avoided and that for any negative input, there exists a representable value of its absolute value which is positive.In a two's complement representation, thisThis excludes the most negative value. -- end note]
Remarks: For signed integer types,Change in 29.7.2 [atomics.types.int] paragraph 7:arithmetic is defined to use two's complement representation.the result is as if the object value and parameters were converted to their corresponding unsigned types, the computation performed on those types, and the result converted back to the signed type. [ Note: There are no undefined results arising from the computation. -- end note]
Remarks: For signed integer types,arithmetic is defined to use two's complement representation.the result is as if the object value and parameters were converted to their corresponding unsigned types, the computation performed on those types, and the result converted back to the signed type. [ Note: There are no undefined results arising from the computation. -- end note]