C++ Logo

sg12

Advanced search

Re: [ub] [c++std-ext-14598] Re: Sized integer types and char bits

From: Richard Smith <richardsmith_at_[hidden]>
Date: Fri, 25 Oct 2013 12:23:56 -0700
On Fri, Oct 25, 2013 at 11:41 AM, Gabriel Dos Reis <gdr_at_[hidden]>wrote:

> Matt Austern <austern_at_[hidden]> writes:
>
> | On Fri, Oct 25, 2013 at 10:31 AM, Jeffrey Yasskin <jyasskin_at_[hidden]>
> wrote:
> |
> |
> |
> | Richard explicitly asked whether any such C++ users exist or are
> | likely to exist in the future, and nobody's come up with any
> examples.
> | So we appear to have a choice between helping some theoretical people
> | or helping some actual people. (We help the actual people by telling
> | them what to expect in the standard, while now they have to test and
> | hope they find the right subset of undefined or
> implementation-defined
> | behavior that's actually guaranteed to work.)
> |
> |
> | It's actually a little worse than that. Testing can reveal what your
> | implementation does today, with your particular input, with one set
> | of compiler flags. No amount of testing can reveal what guarantees
> | your implementation makes.
>
> There are two separate issues here:
>
> (1) whether we want C++ to continue to support non-two's complement
> binary representation
> (2) what we want to say about overflowing shift arithmetic
>
> Requirint two's complement does not necessarily solve (2). And solving
> (2) does not necessarily imply "no" to (1).


Agreed. It would definitely be interesting to complete Jeffrey's list of
the things we could define if we standardized 2s complement, and then
investigate how many of these we are comfortable defining without
specifying 2s complement. So far, we have:

1) overflowing unsigned->signed conversions
2) right-shifts on negative operands
3) bitwise operators

Are there others?

(1) and (2) are currently implementation-defined; (3) seems underspecified
in the current standard.

[I think for consistency we should at least make (3) say that bitwise
operators on positive operands act as "expected" (that is, they give the
result that a 2s complement, 1s complement or sign-magnitude machine
would), and we should make these operations on other machines
implementation-defined.

More generally, we should at least say that each integral type must be one
of 1s complement, 2s complement or sign-magnitude. C currently requires
this (C99/C11 6.2.6.2/2), but C++ does not (3.9.1/7's list of
representations is not normative and not restrictive). 7.2/8 implies that
we don't support other representations, but there's no normative
justification for this assumption.]

If we require that either (1) or (3) acts as-if 2s complement, that
actually rules out 1s complement and sign-magnitude representations,
because these expressions compute a value that does not exist in the other
representations (-2147483648 for a 32-bit integer):

  int(unsigned(INT_MAX) + 1) // for (1)
  int(-1 ^ INT_MAX) // for (3)

We could define that (2) acts as-if 2s complement (divide by 2^N and round
down). I think that's the least valuable operation to define of the three,
though.

Received on 2013-10-25 21:23:58