5

Does the C++11 standard guarantee that the unary minus of a zero-valued signed integer is zero?

For example:

int zero = 0;
int n = -zero;
int m = -0;
assert(memcmp(&n, &zero, sizeof(int)) == 0);
assert(memcmp(&m, &zero, sizeof(int)) == 0);

I know that -0 and 0 are identical in two's compliment representation, but I'd like to know if the standard allows for the negation of signed integer zero to be negative-zero for other representations, such as one's compliment or signed-magnitude.

All I could find in the C++11 draft is §5.3.1, paragraph 8:

The operand of the unary-operator shall have arithmetic or unscoped enumeration type and the result is the negation of its operand. Integral promotion is performed on integral or enumeration operands. The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand. The type of the result is the type of the promoted operand.

I can't find a definition of negation within the draft.

Motivation: I'm writing a specialized integer number parser for a library (that may be open-sourced eventually) and I want to know if I should be concerned about the possibility of "-0" being interpreted as a negative-zero signed integer on uncommon architectures.

Note: I already know about negative-zero floating-point numbers.

Mat
  • 202,337
  • 40
  • 393
  • 406
Emile Cormier
  • 28,391
  • 15
  • 94
  • 122
  • -0 doesn't exist in assembly, Once the signed bit is set, there is no zero value in x86/x64. Nice question anyway. – Michael Chourdakis Jan 14 '20 at 23:52
  • I don't know if `zero` is considered an "unsigned quantity" according to the spec, even if `zero`'s datatype is signed. – Emile Cormier Jan 14 '20 at 23:59
  • At the C++ level it might be defined, but how will it implemented? The code you have posted will set 0 and -0 to the same value in assembly generation. At the machine level there is no -0. – Michael Chourdakis Jan 15 '20 at 00:01
  • Any system that uses twos-complement under the hood has no internal way to represent negative-zero, and last I heard twos-complement was ubiquitous to the point of being nearly universal. – dmckee --- ex-moderator kitten Jan 15 '20 at 00:01
  • @MichaelChourdakis On one-complement or signed-magnitude architectures, it's possible to represent a -0 integer, though I admit they are now rare. C++ is not (yet) strictly bound to two's compliment integers, though there is a proposal to make it so: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r0.html – Emile Cormier Jan 15 '20 at 00:07
  • @dmckee the first assembler I used was for a ones-complement machine. Yes, I'm that old. – Mark Ransom Jan 15 '20 at 00:07
  • I realize my question is an academic one, as I don't foresee my library to be run on some old UNIVAC mainframe. – Emile Cormier Jan 15 '20 at 00:17
  • This is what I have; I'm sure the compiler will optimize that into a simple return expression on modern architectures: `if (isSignedOrUnsignedZeroString()) return negative ? ParseEvent{int{-0}} : ParseEvent{int{0}}` – Emile Cormier Jan 15 '20 at 00:26
  • There are no C++11 compilers for one's complement platforms so the question is about some other world. – Öö Tiib Jan 15 '20 at 00:44
  • 2
    The C standard specifies a limited set of operations that *may* produce a negative zero. Unary `-` is not in that set. (See [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) 6.2.6.2 paragraph 3.) I don't see any similar wording in the C++11 standard. In C, *negative zero* is a representation, not a value as such, and it compares equal to an ordinary zero. (And of course it doesn't exist in 2's-complement.) – Keith Thompson Jan 15 '20 at 01:00

1 Answers1

0

The standard does not mandate bit patterns for integers, because it is meant to be applicable to the widest possible range of machines. It is entirely possible for a C++ compiler to use ones-complement, where zero and negative zero would be different.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • It would require a redefinition of all the math on it, something impossible (and useless). – Michael Chourdakis Jan 15 '20 at 00:07
  • @MichaelChourdakis I don't see why that follows. I've used a ones-complement processor, and I assure you math was not impossible. – Mark Ransom Jan 15 '20 at 00:10
  • You would break all 1-1 functions for example, because there would be two xs for one y. – Michael Chourdakis Jan 15 '20 at 00:12
  • 1
    @MarkRansom I understand the standard does not mandate bit patterns, but it could mandate the result of an arithmetic expression. I'm not well-versed enough in standardese to know if the latter it true. – Emile Cormier Jan 15 '20 at 00:14
  • 3
    My understanding is that [C++20 will mandate two's complement signed integers](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r0.html) (and C2x probably will too). Of course, this question is specifically about C++11. – jamesdlin Jan 15 '20 at 00:15
  • The question is whether a unary `-` applied to `0` can yield a negative zero representation. Hypothetically, the C++ standard *could* have said that such a result must be normalized to a normal `0` representation. See also my comment on the question regarding what C11 has to say about this (apparently more than C++11 does). – Keith Thompson Jan 15 '20 at 01:02
  • The standard does place several restrictions on the bit patterns used for integers – M.M Jan 15 '20 at 01:10
  • @M.M I would welcome an answer that quoted a relevant part of the standard. – Mark Ransom Jan 15 '20 at 01:15