【问题标题】:Why does unary minus perform integral promotion?为什么一元减法执行积分提升?
【发布时间】:2012-08-02 20:09:46
【问题描述】:
const auto min = -std::numeric_limits<T>::max();
T x = min; // conversion from 'const int' to 'short', possible loss of data

T 是一个模板参数,在这种情况下是 short。一元减号显然执行积分提升。

  • 为什么一元减号会执行积分提升?
  • 如果将auto 更改为T,则不会生成警告,但应该将int 分配给short。为什么没有警告(可能是 VS 很花哨)?

【问题讨论】:

  • "为什么一元减号执行积分提升?"因为标准是这么说的(在 5.3.1. (7) 中)。
  • @DanielFischer:但在制定标准的过程中做出的每个决定肯定都有其背后的原因,不是吗?如果可能的话,帮助人们理解这个推理并不是一件坏事。
  • @EdS。是的,希望这些决定背后是有原因的。我不知道它们的原因,但我怀疑这至少部分是“因为它在 C 中就是这样”。为什么在 C 语言中会这样?我怀疑这是因为让 CPU 处理其本机类型而不将结果转换回原始类型更简单。但这只是猜测。
  • @DanielFischer(第 1 条评论):这个答案让我非常恼火(我敢肯定还有很多其他人)它甚至都不好笑......
  • 如果一些算术运算遵循整数提升规则而一些被豁免,那会不会更奇怪?然后你会问“为什么在应用整数提升时有两组不同的规则?为什么它们不能保持一致?”

标签: c++ auto integer-promotion


【解决方案1】:

简短回答:(现在很长,因为人们想对英语过分迂腐,而英语本身并不准确)。

它不是明确的(如一元减号mathematical)。 但作为对 POD 数据的任何操作(包括一元减号 operation)的一部分,对输入参数(可用于和操作的最小整数类型为 int)进行隐式检查,因此对在一元减号之前输入(mathematical 部分不是操作部分)。 POD 上所有操作的输出与输入参数相同(应用积分提升后)。因此这里的输出也是int

长答案:

在 C(以及 C++)中,发生 POD 操作的最小类型是 int。因此,在应用一元减号之前,该值将转换为 int。然后应用一元减号。因此表达式的结果是int

请看这里:Implicit type conversion rules in C++ operators

【讨论】:

    【解决方案2】:

    一元减号执行整数提升,因为整数类型的所有算术运算符都这样做。建立这个约定可能是出于性能原因(通常 int 是最适合硬件上的整数运算的大小),也许是因为有时不限于较小的整数类型的范围很有用。

    我见过人们做的错误:

    uint64_t i = 1 << 33; // use 64-bit type to ensure enough bits to hold the result
    

    但这是一个错误,因为1 &lt;&lt; 33 的结果不依赖于它被分配的内容。 (今天我们对此有警告)。解决方案,很丑,是手动强制其中一个操作数足够大:uint64_t i = static_cast&lt;uint64_t&gt;(1) &lt;&lt; 33

    整体提升恰好可以避免使用较小类型的相同类型的错误,这在 C 以这种方式设计时很常见:

    short a = 30000, b = 20000
    int i = a + b;
    

    在任何情况下,“它不必是合乎逻辑的。这是法律。”

    【讨论】:

      【解决方案3】:

      我认为这是为了解释 C/C++ 假设的理想计算机模型。计算在寄存器中执行,这意味着结果的大小将是机器字。因此“自动”扩展

      【讨论】:

        【解决方案4】:

        我相信这是(部分)因为short 的否定可能无法表示为short
        (如果short 是16 位并且int 更大,则-215 可能需要升级到int。)

        当然,不能保证int 更大,但它(通常?)无论如何都是机器的最佳数据类型,因此尝试将其提升为int 是有意义的,因为可能没有性能无论如何都要花钱。

        【讨论】:

          猜你喜欢
          • 2012-08-19
          • 1970-01-01
          • 2020-01-25
          • 1970-01-01
          • 1970-01-01
          • 2016-10-24
          • 2016-04-01
          • 1970-01-01
          • 2017-10-20
          相关资源
          最近更新 更多