为什么uint8_t + uint8_t导致int?

时间:2017-01-11 13:13:55

标签: c++ types

我注意到,对于8位变量的简单操作,变量在操作完成之前转换为32位int,然后转换回8位变量。

举个例子,这个c ++程序:

#include <iostream>
#include <cstdint>

int main( void )
{
  uint8_t a = 1;
  uint8_t b = 2;

  std::cout << "sizeof(a)   = " << sizeof( a ) << std::endl;
  std::cout << "sizeof(b)   = " << sizeof( b ) << std::endl;
  std::cout << "sizeof(a+b) = " << sizeof( a+b ) << std::endl;

  return 0;
}

产生以下输出:

sizeof(a)   = 1
sizeof(b)   = 1
sizeof(a+b) = 4

所以我们可以理解发生的事情是:

uint8_t c = (uint8_t)((int)(a) + (int)(b));

显然,它似乎在this论坛中所述的C规范中。

此外,在Visual Studio 2013中,编写

auto c = a + b; 

将鼠标指针悬停在c上表示该类型为int

问题是:

  • 为什么是需要转换的,为什么它在规范中? (如果可能的话,有了答案,我希望外部信息来源可以阅读更多有关该主题的内容(例如MSDN,cppreference)。)
  • 这对性能有何影响?

2 个答案:

答案 0 :(得分:6)

这是由integral promotion规则引起的。具体地

  

小整数类型(例如char)的Prvalues可以转换为更大整数类型的prvalues(例如int)。 特别是,算术运算符不接受小于int的类型作为参数,并且在左值到右值转换后自动应用整数提升(如果适用)。此转换始终保留该值。

答案 1 :(得分:2)

  

问题是:

     
      
  • 为什么需要转换,为什么它在规范中? (如果可能的话,有了答案,我希望了解更多的外部信息来源   关于这个问题(如MSDN,cppreference)。)
  •   
  • 这对性能有何影响?
  •   

那么,

  • 可以找到C ++算术运算符取整数操作数的要求here

  • 可以找到积分促销的规则here

至于为什么它在规范中。假设......虽然CPU可能具有可以在8位整数上运行的指令,但在CPU内,写入/读取小于寄存器宽度的整数可能涉及您不知道的屏蔽。

假设您有32位寄存器宽度。添加两个8位整数通常需要一些屏蔽来获取8位部分并用零填充剩余的24位... ALU将对寄存器中的数据进行处理并将结果存储为完全寄存器写入(32位)。然后另一个掩码,如果你强制转换,将结果检索为8位整数。

所以推广它并不需要花费任何成本,因为无论如何CPU都会这样做。

请参阅:On 32-bit CPUs, is an 'integer' type more efficient than a 'short' type?

即使是您的regular 32bit operations on 64bits