Why does this code compile with g++ but not gcc?

别来无恙 提交于 2019-12-13 04:25:48

问题


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?


回答1:


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




回答2:


You can use C syntax (int)(f>>31), it will work for both as this C-syntax is C++-compliant.




回答3:


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 ints 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 2n, 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 ints, -1u is defined to be 0xFFFFFFFFu. The cast to int is not just superfluous, it actually causes the code to be nonportable.



来源:https://stackoverflow.com/questions/24583476/why-does-this-code-compile-with-g-but-not-gcc

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!