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). Types are defined in the <stdint.h> 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:
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 function. What conversion specifier is better to use? We can use the %llu specifier:
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:
printf("%ju", (uintmax_t) var);
The case of the scanf function is similar:
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:
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 and GCC don't treat __int128 and its unsigned analog as extended integer types. Changing the intmax_t and uintmax_t types would break the ABI 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
0