是否有与非可读性相关的原因,而不是每次都不专门使用固定宽度的整数?

时间:2018-12-05 17:13:56

标签: c++ c

假设我们有uint_least8_t var,假设var不可能超过255。 我知道这不是编程的工作方式,“可能”和“永远”都是亵渎神灵,但是,除了使代码复杂化并使其可读性降低之外,什么使始终使用固定宽度的整数成为一个坏主意呢?

2 个答案:

答案 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)接口不兼容。