Date: Fri, 25 Oct 2013 14:37:01 -0500
Richard Smith <richardsmith_at_[hidden]> writes:
| 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.
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
| 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.
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
Received on 2013-10-25 21:37:18