假设我们有uint_least8_t var
,假设var
不可能超过255。
我知道这不是编程的工作方式,“可能”和“永远”都是亵渎神灵,但是,除了使代码复杂化并使其可读性降低之外,什么使始终使用固定宽度的整数成为一个坏主意呢?
答案 0 :(得分:8)
性能是另一个原因。
窄操作数需要附加的缩小/扩展指令。如果没有副作用,就不能总是对其进行优化。有时优化器不够智能,无法安全运行。
以下面的人为例子为例。
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono_literals;
int main()
{
auto tm1 = chrono::high_resolution_clock::now();
unsigned int n = 0;
unsigned int x = 0; // though, uint8_t would have been enough!
for (unsigned int i = 0; i < 1000000000; i++) {
n += (x * i);
x = (n + 1) & 0x7F;
}
auto tm2 = chrono::high_resolution_clock::now();
cout << n << ", " << (tm2 - tm1) / 1.0s << " s" << endl;
}
如果我们将x
的类型从unsigned int
更改为uint8_t
,则使用GCC 7.2编译时,应用程序的运行速度将降低15%(x86-64上的运行时间由2s而不是1.7s) -O3
全面优化)。
使用32-bit x
进行组装:
.L2:
imul eax, edx
inc edx
add ebx, eax
lea eax, [rbx+1]
and eax, 127
cmp edx, 1000000000
jne .L2
使用8-bit x
进行组装:
.L2:
movzx eax, al ; owww!
imul eax, edx
inc edx
add ebp, eax
lea eax, [rbp+1]
and eax, 127
cmp edx, 1000000000
jne .L2
答案 1 :(得分:4)
与其他代码的兼容性,并且不施加任意限制。
在典型的C程序中使用的大部分整数变量是数组索引,对象计数等。这些值固有地不可表示作为固定宽度的整数类型,其宽度在编写程序的时间;可能的范围因实现方式而异。 (这与以下事实有关:给定的C实现不是与Turing等效的;只有无限的实现家族,通过Transdichotomous model是)。当然,您可以决定,您只想支持最多2 ^ 32(例如)一个给定的东西,因此可以使用固定宽度类型,但这是反习惯的,并且这样的代码与使用size_t
并且可能正在传递或接受更大对象的典型(包括std lib)接口不兼容。