许多样式指南,比如 Google 推荐在索引数组时使用 int
作为默认整数。随着64位平台的崛起,大多数时候 int
只有32位,这并不是平台的自然宽度。因此,除了简单的相同之外,我看不出有任何理由保持这种选择。我们清楚地看到,在编写以下代码时:
double get(const double* p, int k) {
return p[k];
}
编译成
movslq %esi, %rsi
vmovsd (%rdi,%rsi,8), %xmm0
ret
其中第一条指令将32位整数提升为64位整数。
如果将代码转换为
double get(const double* p, std::ptrdiff_t k) {
return p[k];
}
生成的程序集现在是
vmovsd (%rdi,%rsi,8), %xmm0
ret
这清楚地表明,与使用 int
相比,使用 std::ptrdiff_t
的 CPU 感觉更自在。许多 C + + 用户已经迁移到 std::size_t
,但是我不想使用无符号整数,除非我真的需要模 2^n
行为。
在大多数情况下,使用 int
并不会影响性能,因为未定义的行为或有符号整数溢出允许编译器在内部将任何 int
提升为处理索引的循环中的 std::ptrdiff_t
,但我们从上面清楚地看到,编译器对 int
并不熟悉。此外,在64位平台上使用 std::ptrdiff_t
将使溢出发生的可能性降低,因为我看到越来越多的人在处理比 2^31 - 1
更大的整数时被 int
溢出困住,而这种情况在当今变得非常普遍。
从我所看到的来看,使 int
独立的唯一原因似乎是像 5
这样的字面值是 int
,但是我不认为如果我们将 std::ptrdiff_t
作为默认整数移动到 std::ptrdiff_t
会导致任何问题。
我的小公司写的所有代码都将使用行业标准整数 std::ptrdiff_t
。有什么理由说这是个错误的选择吗?
PS: 我同意这个事实,名字 ABC0是丑陋的,这就是为什么我已经把它的类型定义为 il::int_t
看起来好一点。
PS: 因为我知道很多人会建议我使用 std::size_t
作为默认整数,我真的想说清楚,我不想使用无符号整数作为我的默认整数。使用 std::size_t
作为 STL 的默认整数是一个错误,比雅尼·斯特劳斯特鲁普和标准委员会在视频 互动面板: 问我们任何问题时间42:38和1:02:50都承认了这一点。
附注: 在性能方面,据我所知,在任何64位平台上,ABC0、 ABC1和 ABC2的编译方法对于 int
和 ABC4都是相同的。所以在速度上没有区别。如果除以编译时常数,速度是相同的。只有在对 ABC6一无所知的情况下除以 ABC5,才能在64位平台上使用32位整数使您在性能方面略有优势。但这种情况是如此罕见,因为我没有看到一个选择从 ABC4移开。当我们处理矢量化代码时,这里有一个明显的区别,而且越小越好,但是这是一个不同的故事,没有理由坚持使用 int
。在这些情况下,我建议使用固定大小的 C + + 类型。