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很高级)?
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很高级)?mathematical
)。但是,在对POD数据进行任何操作(包括一元减号operation
)时,会对输入参数进行隐式检查(可以在操作中使用的最小整数类型是int
),因此一元减号(mathematical
部分而非operation
部分)之前会进行整数提升。POD上所有操作的输出与输入参数相同(应用了整数提升之后)。因此,这里的输出也是int
。int
。因此,在应用一元减号之前,该值将转换为int。然后应用一元减号。因此表达式的结果是int
。一元减号执行整数提升,因为整数类型上的所有算术运算符都这样做。这种惯例可能是出于性能原因建立的(通常int是最适合硬件上的整数运算的大小),也许是因为有时不限制较小整数类型的范围是有用的。
我看过一些bug,人们会做:
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++所假设的理想计算机模型。计算是在寄存器中执行的,这意味着结果的大小将是机器字。因此出现了“自动扩展”的情况。
我认为这部分是因为一个short
的负数可能无法表示为一个short
。
(-215如果short
是16位且int
更大,则可能需要提升为int
。)
当然,不能保证int
更大,但它通常是机器上最优数据类型,因此尝试将其提升为int
是有意义的,因为可能没有性能成本。