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.

> 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