【问题标题】:Why does this code compile with g++ but not gcc?为什么这段代码用 g++ 编译而不是 gcc?
【发布时间】:2014-07-05 05:59:00
【问题描述】:

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

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

我会假设在 C++ 中,

int(f >> 31)

是一个构造函数,但这让我想知道为什么它包含在代码中。有必要吗?

【问题讨论】:

  • 有人用 C++ 而不是 C 编写代码 - 那么问题出在哪里?
  • int(f >> 31) 是一个函数式转换;与 C 风格的 (int) (f >> 31) 含义相同。您需要演员表,以便您可以在结果上使用-(一元否定),因为f,并且通过扩展f >> 31unsigned
  • 也就是说,这是一个非常糟糕的代码,因为它取决于int 在系统中的表示的细节。一个补码系统和一个二进制补码系统会在这里给你完全不同的结果......
  • 这个演员阵容有多重要?
  • @LưuVĩnhPhúc:很遗憾,我也注意到了这一点。阿斯拉维尔一直问问题,期待帮助是很不礼貌的,但是他懒得给那些试图帮助他的人打勾……这与声誉无关,但人们会不必要地继续访问他的问题因为在首页上,它显示为没有可接受的答案...那是浪费时间...

标签: c++ c gcc casting g++


【解决方案1】:

C 不支持C++ "function-style" casting。你需要这样写

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

cast operator

【讨论】:

    【解决方案2】:

    您可以使用 C 语法 (int)(f>>31),因为此 C 语法符合 C++ 标准,所以两者都适用。

    【讨论】:

      【解决方案3】:

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

      这个演员阵容有多重要?

      实际上,这段代码看起来太聪明了。 f >> 31 只保留f 中的最高位,所以它要么是1,要么是0。然后代码将其转换为int 并对其执行一元否定,得到-10,最后将结果与0x80000000 进行位或运算,设置最高位,然后存储结果进入mask。假设一个二进制补码系统,-1 的表示是0xFFFFFFFF,所以如果设置了f 的最高位,mask 将变为0xFFFFFFFF,否则0x80000000

      然而,问题在于ints 不必使用二补码。例如,如果系统是一个补码,-1 的表示将是 0xFFFFFFFE,如果系统是符号量级,-1 将是 0x80000001mask 将具有错误的值。

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

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

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

      【讨论】:

        猜你喜欢
        • 2019-11-15
        • 1970-01-01
        • 2020-11-13
        • 2013-08-08
        • 1970-01-01
        • 1970-01-01
        • 2020-02-02
        • 2011-10-01
        • 1970-01-01
        相关资源
        最近更新 更多