The following piece of code compiles with g++ and not gcc, and am stuck wondering why?
inline unsigned FloatFlip(unsigned f)
{
unsigned mask = -int(f >> 31) | 0x80000000;
return f ^ mask;
}
I would assume that in C++,
int(f >> 31)
is a constructor but that leaves me wondering why it's included in the code. Is it necessary?
C doesn't support the C++ "function-style" casting . You need to write it like this
unsigned mask = -(int)(f >> 31) | 0x80000000;
See cast operator
您可以使用C语法(int)(f>>31)
,因为此C语法符合C ++,因此对这两种语法都适用。
As the other answers discussed, int(f >> 31)
is a C++ function-style cast, and it has the same meaning as the C-style (int) (f >> 31)
.
How is this cast important?
Actually, this code looks like it's trying to be too clever. f >> 31
retains only the highest-order bit in f
, so it's either 1
or 0
. The code then casts it to an int
and performs unary negation on it, giving you either -1
or 0
, and finally bitwise-OR's the result with 0x80000000
, which sets the highest bit and then stores the result into mask
. Assuming a two's complement system, -1
's representation is 0xFFFFFFFF
and so mask
will become 0xFFFFFFFF
if the highest-order bit of f
is set, and 0x80000000
otherwise.
The problem, however, is that int
s do not have to use two-complement. If the system is one's complement, for instance, -1
's representation would be 0xFFFFFFFE
, and if the system is sign-magnitude, -1
would be 0x80000001
, and mask
will have the wrong value.
The irony is that unary negation for unsigned operands is well-defined to do what the author of this code presumably wanted to do, in §5.3.1 [expr.unary.op]/p8 of the standard:
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.
In other words, assuming 32-bit int
s, -1u
is defined to be 0xFFFFFFFFu
. The cast to int
is not just superfluous, it actually causes the code to be nonportable.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.