获取C++中最大的有符号整数类型

Get the largest signed integer type in C++

假设我必须接受一个大小作为处理数组的接口的参数。对于 e.x.

void doSomethingRelatedToArrays(const size_t length)

在这里,我使用 size_t 时考虑了以下几点:

但是,我不应该在我的接口中使用无符号类型,因为客户端可以传入一个负数,它被隐式转换为一个无符号数,我没有任何方法在我的方法中验证它。请参阅 Scott Meyer 关于此主题的文章 here

所以,我应该将有符号整数类型传递给 API。但是如何才能得到系统中最大的有符号整数类型呢?是否有任何类似于 size_t 的类型定义已签名?或者我应该只使用 size_t 来代替?

size_t 的带符号等价物就是 ssize_t,但这种类型在 C99 标准中没有定义,即使许多编译器都知道它。

对于 C99 标准,最大的有符号整数类型定义为 intmax_t

参考:7. 库/7.18 整数类型/7.18.1.5 最大宽度整数类型

要使用的标准类型是 std::intmax_t,它在 <cstdint> 中定义。要获得最大值,您可以使用 std::numeric_limits<intmax_t>::max().

示例代码:

#include <cstdint>
#include <iostream>
#include <limits>

int main(int argc, char* argv[]) {
    std::cout << "max size = " << std::numeric_limits<intmax_t>::max() << std::endl;
}

最近的 C 和 C++ 标准中最大的有符号整数类型是 long long。除非有比 long long 宽的类型,否则您始终可以使用它。如果你想成为未来的证明,使用 intmax_t.


size_t is always typedef-ed to the largest unsigned integer type in the system

完全不正确!!! ❌

size_t 在 32 位系统中通常也是 32 位类型,显然 不是 可能的最宽类型。它只能保证大到足以表示系统上最大对象的大小。 long long 在这种情况下显然要宽得多。在许多 16 位系统中它只有 16 位,甚至与 long.

的范围不一样

如果需要 size_tptrdiff_t 可以用作已签名的副本。但也不是最大的那种。

For char arrays shorter than PTRDIFF_MAX, std::ptrdiff_t acts as the signed counterpart of std::size_t: it can store the size of the array of any type and is, on most platforms, synonymous with std::intptr_t

http://en.cppreference.com/w/cpp/types/ptrdiff_t

在 C++20 中引入了 std::ssize,猜猜看,它还使用 ptrdiff_t 作为 size_t[ 的签名对应物=30=]

But how can I get the largest signed integer type in the system?

在 C++11 的 <cstdint> 中,您可以找到类型 intmax_t,它是在 C 标准 (7.20.1.5) 之后定义的:

The following type designates a signed integer type capable of representing any value of any signed integer type


Is there any typedef similar to size_t which is signed?

不,不在 C++ 标准中。 POSIX 定义 ssize_t, :

  • 它并不是要取代 size_t(它本身也受到 POSIX 的更多限制)
  • 不是 store/pass 负值,而是表示错误:

    ssize_t shall be capable of storing values at least in the range [-1, {SSIZE_MAX}].


So, I should pass in signed integer type to the API. (...) Or should I just use size_t instead?

如果您的接口旨在处理 C++ 数组,则 size_t 是标准保证能够保存任何可能的数组索引的唯一类型。使用任何其他类型,您可能(理论上)失去寻址所有数组的能力(甚至在您链接的文章中提到)。

因此,将 size_t 用于索引目的是常见且习惯的 - 并被许多库(包括 STL)使用。