const auto min = -std::numeric_limits<T>::max();
T x = min; // conversion from 'const int' to 'short', possible loss of data
T 是一个模板参数,short
在这种情况下是 a。一元减号显然执行积分提升。
- 为什么一元减法执行积分提升?
- 如果
auto
更改为T
不生成警告,但应该将 int 分配给 short。为什么没有警告(可能是 VS 很花哨)?
const auto min = -std::numeric_limits<T>::max();
T x = min; // conversion from 'const int' to 'short', possible loss of data
T 是一个模板参数,short
在这种情况下是 a。一元减号显然执行积分提升。
auto
更改为T
不生成警告,但应该将 int 分配给 short。为什么没有警告(可能是 VS 很花哨)?Short answer: (now long because people want to be excessively pedantic about English which by its very nature is not exact).
Its not explicitly (as in the unary minus mathematical
).
But as part of any operation (this includes unary minus operation
) on POD data there is an implicit check on input parameters (the smallest integer type that can be used in and operation is int
) so there is integral promotion on the input before the unary minus (the mathematical
part not the operation part). The output of all operations on POD is the same as the input parameters (after integral promotion is applied). Thus here the output is also an int
.
Long answer:
In C (and thus C++) the smallest type that POD operations happen on is int
. So before the unary minus is applied the value is converted to int. Then the unary minus is applied. The result of the expression is thus int
.
一元减号执行整数提升,因为整数类型上的所有算术运算符都这样做。建立这个约定可能是出于性能原因(通常 int 是最适合硬件上的整数运算的大小),也许是因为有时不限于较小的整数类型的范围很有用。
我见过人们做的错误:
uint64_t i = 1 << 33; // use 64-bit type to ensure enough bits to hold the result
但这是一个错误,因为结果1 << 33
不取决于分配给什么。(今天我们对此有警告)。丑陋的解决方案是手动强制其中一个操作数足够大:uint64_t i = static_cast<uint64_t>(1) << 33
整体提升恰好避免了具有较小类型的相同类型的错误,这在 C 以这种方式设计时很常见:
short a = 30000, b = 20000
int i = a + b;
无论如何,“它不必是合乎逻辑的。这是法律。”
我认为这是为了解释 C/C++ 假设的理想计算机模型。计算在寄存器中执行,这意味着结果的大小将是机器字。因此“自动”扩展
我相信这是(部分)因为 a 的否定short
可能无法表示为 a short
。
(-2 15可能需要提升到int
ifshort
是 16 位并且int
更大。)
当然,不能保证int
更大,但它(通常?)无论如何都是机器的最佳数据类型,因此尝试将其提升为有意义的,int
因为无论如何可能没有性能成本。