我注意到,对于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
。
问题是:
答案 0 :(得分:6)
这是由integral promotion规则引起的。具体地
小整数类型(例如
char
)的Prvalues可以转换为更大整数类型的prvalues(例如int
)。 特别是,算术运算符不接受小于int的类型作为参数,并且在左值到右值转换后自动应用整数提升(如果适用)。此转换始终保留该值。
答案 1 :(得分:2)
问题是:
- 为什么需要转换,为什么它在规范中? (如果可能的话,有了答案,我希望了解更多的外部信息来源 关于这个问题(如MSDN,cppreference)。)
- 这对性能有何影响?
那么,
至于为什么它在规范中。假设......虽然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?。