简体   繁体   中英

Get the largest signed integer type in C++

Let's say I have to accept a size as an argument to an interface which deals with arrays. For ex

void doSomethingRelatedToArrays(const size_t length)

Here, I used size_t with the following in mind:

  • length must always be positive
  • size_t is always typedef-ed to the largest unsigned integer type in the system. std::size_t can store the maximum size of a theoretically possible object of any type.

However, I should not use unsigned types in my interfaces because the client can pass in a negative number, which is implicitly converted to an unsigned number and I do not have any way of validating it in my method. Refer to Scott Meyer's article on this subject here .

So, I should pass in signed integer type to the API. But how can I get the largest signed integer type in the system? Is there any typedef similar to size_t which is signed? Or should I just use size_t instead?

The signed equivalent of size_t is simply ssize_t but this type is not defined in C99 standard even if it is known to many compilers.

For the C99 standard the largest signed integer type is defined as intmax_t .

Reference : 7. Library / 7.18 Integer types / 7.18.1.5 Greatest-width integer types

The standard type to use is std::intmax_t which is defined in <cstdint> . To get the maximum value you can use std::numeric_limits<intmax_t>::max() .

Sample code:

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

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

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

In C++11's <cstdint> you can find type intmax_t , which is defined after the C standard (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?

No, not in the C++ standard. POSIX defines ssize_t , but :

  • it is not meant to replace size_t (which itself is also more restricted by POSIX)
  • is not meant to store/pass negative values, but to indicate error:

    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?

If your interface is meant to deal with C++ arrays, size_t is the only type that is assured by the standard to be able to hold any of the possible array indexes. Using any other type you might (in theory) loose ability to address all of the array (which is even noted in the article you linked).

Using size_t for indexing purposes is therefore common and customary - and used by many libraries (including STL).

The largest signed integer type in recent standards of C and C++ is long long . Until there is a type wider than long long you can always use it. If you want to be more future proof, use intmax_t

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

That's completely incorrect!!!

size_t in 32-bit systems is typically also a 32-bit type, which obviously not the widest type possible. It's only guaranteed to be big enough to represent the size of the biggest object on the system. unsigned long long is much wider in that case


In case size_t is needed, ptrdiff_t can be used as a signed counterpart. But it's not the biggest type either.

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

In C++20 std::ssize was introduced and guess what, it also uses ptrdiff_t as the signed counterpart of size_t

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM