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

Gabriel Dos Reis gdr at axiomatics.org
Fri Oct 25 21:37:01 CEST 2013


Richard Smith <richardsmith at google.com> writes:

| On Fri, Oct 25, 2013 at 11:41 AM, Gabriel Dos Reis <gdr at axiomatics.org> wrote:
| 
|     Matt Austern <austern at google.com> writes:
| 
|     | On Fri, Oct 25, 2013 at 10:31 AM, Jeffrey Yasskin <jyasskin at google.com>
|     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.

Agreed.

| 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.

At the very least, we should clarify the standards that the list in 3.9.1/7
is exhaustive.  I don't remember why we didn't synchronize on this for C++11.

-- Gaby


More information about the ub mailing list