Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS‑Studio license for Microsoft MVP specialists
* By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
* By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
* By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you do not see the email in your inbox, please check if it is filtered to one of the following folders:

  • Promotion
  • Updates
  • Spam

Webinar: C++ semantics - 06.11

>
>
>
Intmax_t / uintmax_t

intmax_t / uintmax_t

Jul 30 2024

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

Popular related articles


Comments (0)

Next comments next comments
close comment form