代码用g ++但不是gcc编译

下面的代码用g ++而不是gcc编译,我想知道为什么?

inline unsigned FloatFlip(unsigned f) { unsigned mask = -int(f >> 31) | 0x80000000; return f ^ mask; } 

我假设在C ++中,int(f >> 31)是一个构造函数,但这让我想知道为什么它包含在代码中。是否有必要?

C不支持C ++“函数式”转换。 你需要这样写

 unsigned mask = -(int)(f >> 31) | 0x80000000; 

你可以使用C语法(int)(f>>31) ,因为这个C语法符合C ++,所以它都适用。

正如讨论的其他答案一样, int(f >> 31)是一个C ++函数式转换,它与C-style (int) (f >> 31)具有相同的含义(int) (f >> 31)

这个演员如何重要?

实际上,这段代码看起来似乎太聪明了。 f >> 31仅保留f >> 31的最高位,因此它为10 。 然后代码将它转换为int并对其执行一元否定,给出-10 ,最后按位OR的结果为0x80000000 ,它设置最高位,然后将结果存储到mask 。 假设一个二进制补码系统, -1的表示为0xFFFFFFFF ,因此如果设置了f的最高位,则mask将变为0xFFFFFFFF ,否则为0x80000000

然而,问题是int不必使用二补码。 例如,如果系统是一个补码,则-1的表示将是0xFFFFFFFE ,如果系统是符号幅度,则-1将是0x80000001 ,并且mask将具有错误的值。

具有讽刺意味的是,对于无符号操作数的一元否定是明确定义的,以执行该代码的作者可能想做的事情,在标准的§5.3.1[expr.unary.op] / p8中:

一元运算符的操作数应具有算术或无范围的枚举类型,结果是其操作数的否定。 对整数或枚举操作数执行整体提升。 通过从2 n减去其值来计算无符号数量的负数,其中n是提升的操作数中的位数。 结果的类型是提升的操作数的类型。

换句话说,假设32位int-1u定义为0xFFFFFFFFu 。 转换为int不仅仅是多余的,它实际上导致代码不可移植。