First of all, your first premise is wrong:
int negzero = -0;
should produce a normal zero on any conformant architecture.
References for that were given in @101010's answer:
3.9.1 Fundamental types [basic.fundamental] §3:
... The signed and unsigned integer
types shall satisfy the constraints given in the C standard, section 5.2.4.2.1.
Later in C reference:
5.2.4.2.1 Sizes of integer types
... Forward references: representations of types (6.2.6)
and (still C):
6.2.6 Representations of types / 6.2.6.2 Integer types § 3
If the implementation supports negative zeros, they shall be generated only by:
the &, |, ^, ~, <<, and >> operators with arguments that produce such a value;
the +, -, *, /, and % operators where one argument is a negative zero and the result is
zero;
compound assignment operators based on the above cases.
So negzero = -0
is not such a construct and shall not produce a negative 0.
For following lines, I will assume that the negative 0 was produced in a bitwise manner, on an implementation that supports it.
C++ standard does not speak at all of negative zeros, and C standard just say of them that their existence is implementation dependant. I could not find any paragraph explicitly saying whether a negative zero should or not be equal to a normal zero for relational or equality operator.
So I will just cite in C reference : 6.5.8 Relational operators §6
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.92)
The result has type int.
and in C++ 5.9 Relational operators [expr.rel] §5
If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield
true if the specified relationship is true and false if it is false.
My interpretation of standard is that an implementation may allow an alternate representation of the integer value 0 (negative zero) but it is still a representation of the value 0 and it should perform accordingly in any arithmetic expression, because C 6.2.6.2 Integer types § 3 says:
negative zeros[...] shall be generated only by [...] the +, -, *, /, and % operators where one argument is a negative zero and the result is
zero
That means that if the result is not 0, a negative 0 should perform as a normal zero.
So these two lines at least are perfectly defined and should produce 1
:
std::cout<<(1 << negzero)<<std::endl;
std::cout<<(1 >> negzero)<<std::endl;
This line is clearly defined to be implementation dependant:
std::cout<<(~negzero)<<(~zero)<<std::endl;
because an implementation could have padding bits. If there are no padding bits, on a one's complement architecture ~zero
is negzero
, so ~negzero
should produce a 0
but I could not find in standard if a negative zero should display as 0
or as -0
. A negative floating point 0 should be displayed with a minus sign, but nothing seems explicit for an integer negative value.
For the last 3 line involving relational and equality operators, there is nothing explicit in standard, so I would say it is implementation defined
TL/DR:
Implementation-dependent:
std::cout<<(negzero < zero)<<std::endl;
std::cout<<(negzero <= zero)<<std::endl;
std::cout<<(negzero == zero)<<std::endl;
std::cout<<(~negzero)<<(~zero)<<std::endl;
Perfectly defined and should produce 1:
std::cout<<(1 << negzero)<<std::endl;
std::cout<<(1 >> negzero)<<std::endl;