Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[meta.unary.op] Expand note for has_unique_object_representations #6515

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Eisenwave
Copy link
Contributor

It's a common question in the community for what types std::has_unique_object_representations_v yields false, and why that happens.

I think it's worth expanding this note so that it mentions two very common failure cases:

  • IEC 559 floating-point numbers, which have multiple representations for zero and NaN
  • bool on ARM, which allows for more representations of true than just 0x01

source/meta.tex Show resolved Hide resolved
source/meta.tex Outdated Show resolved Hide resolved
\keyword{true} or \keyword{false} can have multiple object representations.
If \tcode{std::numeric_limits<T>::is_iec559} is \keyword{true}, the
condition does not hold for \tcode{T} because there are multiple object
representations for some values, such as zero.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean plus and minus zero? Those are distinguishable.

Copy link
Contributor Author

@Eisenwave Eisenwave Aug 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe C++ considers them to be the same value based on equality comparison. They are the same value, and positive/negative zero are two value/object representations of it.

Maybe it's worth making this more explicit in the note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, 1/-0 yields a value different from 1/+0 in IEEE, so (regardless of equality comparison), the value +0 seems to be different from -0.

The various IEEE NaN encodings seem a better example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether IEEE 754 floating-point formats are OK. It seems that all patterns of value representations are distinguishable in strong_order ([cmp.alg] p1.3) due to the totalOrder operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frederick-vs-ja non-canonical representations are not ordered, and I believe they aren't otherwise distinguishable in any way:
image

(from the IEEE-754 standard, which presumably has the same totalOrder)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jensmaurer I'm starting to think that even though +0 and -0 compare equal and are otherwise indistinguishable with the builtin relational operators, they are still distinct values.

I'll change the wording to talk about NaN encodings instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-canonical representations are only present for decimal floating-point formats. I'm not sure whether decimal FP is suitable here now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frederick-vs-ja then I've misunderstood what non-canonical means.

Anyhow, all major compilers yield false for std::has_unique_object_representations_v<float> on IEC 559 platforms, so consensus is that floating point numbers don't satisfy it.

The way that totalOrder orders different encodings of NaN could be seen as an ordering imposed on the object representation, without all those possible NaNs being distinct values.

This lack of clarity sounds like a core issue to me though, and maybe CWG should add normative wording that decides whether IEC 559 floats have unique object representations or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For IEC 559 floats, quit and signaling NaN can have any sign bit, since the bit is ignored. This means that if quit and signaling are each considered one value, there exist at least two value/object representations of this value.

If a type has padding bits, the condition does not hold;
otherwise, the condition holds true for integral types.
If a type \tcode{T} has padding bits, the condition does not hold for \tcode{T}.
If \tcode{T} is an integral type other than \keyword{bool}, the condition
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has lost the "otherwise": We can have integral types with padding bits, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With C++20 requiring two's complement, maybe not ... unless unsigned integers are padded too, and I think they can be.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can have a 31-bit unsigned int on CHAR_BIT=8 machine.

If a type \tcode{T} has padding bits, the condition does not hold for \tcode{T}.
If \tcode{T} is an integral type other than \keyword{bool}, the condition
holds for \tcode{T}.
The condition might not hold for \keyword{bool} because
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't have "might" in notes, says ISO. "can" is ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants