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