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
 implementationdefined
  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 nontwo'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) rightshifts on negative operands
 3) bitwise operators

 Are there others?

 (1) and (2) are currently implementationdefined; (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 signmagnitude machine would), and we should make
 these operations on other machines implementationdefined.
Agreed.
 More generally, we should at least say that each integral type must be one of
 1s complement, 2s complement or signmagnitude. 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 asif 2s complement, that actually
 rules out 1s complement and signmagnitude representations, because these
 expressions compute a value that does not exist in the other representations
 (2147483648 for a 32bit integer):

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

 We could define that (2) acts asif 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
 implementationdefined
  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 nontwo'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) rightshifts on negative operands
 3) bitwise operators

 Are there others?

 (1) and (2) are currently implementationdefined; (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 signmagnitude machine would), and we should make
 these operations on other machines implementationdefined.
Agreed.
 More generally, we should at least say that each integral type must be one of
 1s complement, 2s complement or signmagnitude. 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 asif 2s complement, that actually
 rules out 1s complement and signmagnitude representations, because these
 expressions compute a value that does not exist in the other representations
 (2147483648 for a 32bit integer):

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

 We could define that (2) acts asif 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 20131025 21:37:18