Reference: [basic.types.trivial]
Issue description
The new definition of "value" in P2434R4 is as follows:
Each trivially copyable type T has an implementation-defined set of discrete values. Each possible value representation of an object of type T corresponds to a distinct implementation-defined subset of this set. These subsets for a type are disjoint, and their union is the set of values; for scalar types other than object pointer types, each contains no more than one value.
Thus for "scalar types other than pointer types", every value representation corresponds to exactly one value (or no value, meaning that the representation is invalid, but that wouldn't change the result of has_unique_object_representations anyway). This is a breaking change for floating-point types because currently, every major compiler accepts the following code:
// Assuming float has the same representation as std::float32_t
static_assert(not std::has_unique_object_representations_v<float>);
Presumably, this is because the single NaN value has a variety of representations (different payloads). This interpretation is also supported by P3938R1 and has strong consensus in SG6 (see discussion during Brno meeting).
By the new definition of "value", unless std::float32_t had padding bits, std::has_unique_object_representations_v<std::float32_t> would have to be true because there is a bijective mapping between values and object representations ([meta.unary.prop]).
Additionally, the new definition of "value" makes floating-point promotion from float to double unimplementable because this conversion requires that "the value is unchanged" ([conv.fpprom]). If every NaN payload corresponds to a distinct value, it is impossible not to change the value when widening the mantissa during the conversion of float to double. That is, changing the amount of payloads bits should be considered a change in payload, and thus a change in value according to [basic.types.trivial].
Suggested resolution
Change the definition of "value" in [basic.types.trivial] as follows:
Each trivially copyable type T
has an implementation-defined set of discrete values.
Each possible value representation of an object of type T
corresponds to
-a distinct
+an
implementation-defined subset of this set.
-These subsets for a type are disjoint,
-and their union is the set of values
-; for scalar types other than object pointer types,
-each contains no more than one value.
Certain operations cause an object to acquire a value representation,
in which case the object’s value is replaced
with an unspecified member of the corresponding subset
that would result in the program having defined behavior, if any.
Reference: [basic.types.trivial]
Issue description
The new definition of "value" in P2434R4 is as follows:
Thus for "scalar types other than pointer types", every value representation corresponds to exactly one value (or no value, meaning that the representation is invalid, but that wouldn't change the result of
has_unique_object_representationsanyway). This is a breaking change for floating-point types because currently, every major compiler accepts the following code:Presumably, this is because the single NaN value has a variety of representations (different payloads). This interpretation is also supported by P3938R1 and has strong consensus in SG6 (see discussion during Brno meeting).
By the new definition of "value", unless
std::float32_thad padding bits,std::has_unique_object_representations_v<std::float32_t>would have to betruebecause there is a bijective mapping between values and object representations ([meta.unary.prop]).Additionally, the new definition of "value" makes floating-point promotion from
floattodoubleunimplementable because this conversion requires that "the value is unchanged" ([conv.fpprom]). If every NaN payload corresponds to a distinct value, it is impossible not to change the value when widening the mantissa during the conversion offloattodouble. That is, changing the amount of payloads bits should be considered a change in payload, and thus a change in value according to [basic.types.trivial].Suggested resolution
Change the definition of "value" in [basic.types.trivial] as follows: