下面的代码用g ++而不是gcc编译,我想知道为什么?
inline unsigned FloatFlip(unsigned f)
{
unsigned mask = -int(f >> 31) | 0x80000000;
return f ^ mask;
}
我认为在C ++中,
int(f >> 31)
是一个构造函数但是让我想知道为什么它包含在代码中。有必要吗?
答案 0 :(得分:8)
C不支持C ++"功能风格"铸件。你需要像这样写
unsigned mask = -(int)(f >> 31) | 0x80000000;
答案 1 :(得分:4)
你可以使用C语法(int)(f>>31)
,因为这个C语法符合C ++,所以它都适用于它们。
答案 2 :(得分:0)
正如讨论的其他答案一样,int(f >> 31)
是一个C ++函数式转换,它与C风格的(int) (f >> 31)
具有相同的含义。
这个演员如何重要?
实际上,这段代码看起来似乎太聪明了。 f >> 31
仅保留f
中的最高位,因此它可以是1
或0
。然后代码将其强制转换为int
并对其执行一元否定,为您提供-1
或0
,最后使用0x80000000
对结果进行按位OR运算,最高位然后将结果存储到mask
。假设有一个二进制补码系统,-1
的表示为0xFFFFFFFF
,如果设置了mask
的最高位,0xFFFFFFFF
将变为f
,并且否则0x80000000
。
然而,问题是int
不必使用二补码。例如,如果系统是一个补码,-1
的表示将是0xFFFFFFFE
,如果系统是符号幅度,-1
将是0x80000001
,{ {1}}将有错误的值。
具有讽刺意味的是,对于无符号操作数的一元否定是明确定义的,以执行此代码的作者可能想做的事情,在标准的§5.3.1[expr.unary.op] / p8中:
一元
mask
运算符的操作数应具有算术或无范围 枚举类型和结果是其操作数的否定。 对整数或枚举操作数执行整体提升。 无符号数量的负数通过减去它来计算 来自2 n 的值,其中n是提升的操作数中的位数。 结果的类型是提升的操作数的类型。
换句话说,假设32位-
s,int
被定义为-1u
。对0xFFFFFFFFu
的强制转换不仅仅是多余的,它实际上导致代码不可移植。