﻿# intmax\_t / uintmax\_t



**Date**: 24\.07\.2015

The _intmax\_t_ and _uintmax\_t_ aliases are special data types defined in the C and C\+\+ standard library\. These integer types represent the value of any signed and unsigned type respectively \(C11 [7\.20\.1\.5](https://open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf)\)\. Types are defined in the [_<stdint\.h\>_](http://www.cplusplus.com/reference/cstdint/) header file with their minimum and maximum values of _INTMAX\_MIN_, _INTMAX\_MAX_, and _UINTMAX\_MAX_\. The C standard doesn't forbid the implementation of these types via extended integer types\.

Let's look at an example of the useful type implementation\. The code handles _var_ of unsigned integer data type defined by the programmer:

```cpp
mytype_t var;
```

The variable length is unknown or may vary depending on the compiler implementation\. The task is to correctly print the value of this variable using the [_printf_](https://en.cppreference.com/w/c/io/fprintf) function\. What conversion specifier is better to use? We can use the _%llu_ specifier:

```cpp
printf("%llu", (unsigned long long)var);
```

However, what if this variable belongs to a type larger than _unsigned long long_, and there is no conversion specifier defined for it? The _uintmax\_t_ type can help here\. 

The length modifier for _intmax\_t_ and _uintmax\_t_ in the conversion specifier is the _j_ letter\. Since any unsigned integer value can be in _uintmax\_t_, casting to the type ensures that the number will be saved\. The correct _var_ output will look as follows:

```cpp
printf("%ju", (uintmax_t) var);
```

The case of the [_scanf_](https://en.cppreference.com/w/c/io/fscanf) function is similar:

```cpp
mytype_t var;
scanf("%llu", &var);
```

However, even this code may lead to incorrect reading of a number if _mytype\_t_ is larger than _unsigned long long_\. Or this code can lead to the _var_ overflow if _mytype\_t_ is less than _unsigned long long_\. We can ensure the correct reading in the following way:

```cpp
mytype_t var;
uintmax_t temp;
scanf("%ju", &temp);
if(temp <= MYTYPE_MAX)
  var = temp;
```

**A note about _\_\_int128_ and its unsigned analog\.** In the case of the Clang or GCC compilers, the _intmax\_t_ and _uintmax\_t_ types are defined as _long long_ and _unsigned long long_ respectively\. [Clang](https://clang.llvm.org/cxx_status.html#n1988) and [GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49595) don't treat _\_\_int128_ and its unsigned analog as extended integer types\. Changing the _intmax\_t_ and _uintmax\_t_ types would break the [ABI](https://en.wikipedia.org/wiki/Application_binary_interface) compatibility with existing applications\.

For example, imagine a program that uses a function that has an _intmax\_t_ parameter in a dynamic library\. If the compiler changes the _intmax\_t_ value and recompiles the program, the program, and the library will reference different types, which will break binary compatibility\.

The use of _intmax\_t_/_uintmax\_t _is a little inconsistent with their intended purposes described in the standard\.

**References**

1. CERT C Coding Standard\. [INT15\-C](https://wiki.sei.cmu.edu/confluence/display/c/int15-c.+use+intmax_t+or+uintmax_t+for+formatted+io+on+programmer-defined+integer+types)\. Use intmax\_t or uintmax\_t for formatted IO on programmer\-defined integer types
1. [Stack Overflow\. What ABI, if any, restricts the size of \[u\]intmax\_t?](https://stackoverflow.com/questions/29927562/what-abi-if-any-restricts-the-size-of-uintmax-t)
1. [Stack Overflow\. Why in g\+\+ std::intmax\_t is not a \_\_int128\_t?](https://stackoverflow.com/questions/21265462/why-in-g-stdintmax-t-is-not-a-int128-t)
1. [Stack Overflow\. Why isn't there int128\_t?](https://stackoverflow.com/questions/29638723/why-isnt-there-int128-t/29638843)