Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top

intmax_t / uintmax_t

15 Ноя 2024

Дата: 24.07.2015

Псевдонимы intmax_t и uintmax_t — специальные типы данных, определённые в стандартной библиотеке C и C++. Они обозначают целочисленные типы, которые позволяют отразить значение любого знакового и беззнакового типа соответственно (C11, п.п. 7.20.1.5). Типы определены в заголовочном файле <stdint.h> вместе со своими минимальными и максимальными значениями INTMAX_MIN, INTMAX_MAX и UINTMAX_MAX. Стандарт C не запрещает реализовывать эти типы через расширенные целочисленные типы.

Рассмотрим пример, когда могут быть полезны эти типы. В коде происходит работа с переменной var беззнакового целочисленного типа данных, определённого программистом:

mytype_t var;

Длина переменной неизвестна или может меняться в зависимости от реализации компилятора. Задача — корректно вывести значение этой переменной с помощью функции printf. Какой спецификатор конверсии следует использовать? Можно воспользоваться спецификатором %llu:

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

Однако что делать, если эта переменная принадлежит к типу, который больше, чем unsigned long long, и для него не определён спецификатор конверсии? Тут на помощь и приходит тип uintmax_t.

Модификатором длины для intmax_t и uintmax_t в спецификаторе конверсии является буква j. Так как любое беззнаковое целочисленное значение может поместиться в uintmax_t, то приведение к этому типу гарантирует сохранение числа. Корректный вывод переменной var будет выглядеть так:

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

Аналогичная ситуация и с функцией scanf:

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

Однако даже такой код может привести к некорректному считыванию числа, если mytype_t больше, чем unsigned long long. Или к переполнению переменной var, если mytype_t меньше, чем unsigned long long. Корректное считывание можно обеспечить следующим образом:

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

Примечание об __int128 и его беззнаковом аналоге. В случае компиляторов Clang или GCC, типы intmax_t и uintmax_t определены как long long и unsigned long long соответственно. Дело в том, что Clang и GCC не рассматривают __int128 и его беззнаковый аналог как расширенные целочисленные типы. Такое изменение повлекло бы за собой изменение типов intmax_t и uintmax_t, что нарушило бы ABI-совместимость с существующими приложениями.

Представьте, что у вас есть программа, которая использует функцию с параметром intmax_t в динамической библиотеке. Если компилятор изменит значение intmax_t и перекомпилирует программу, то она и библиотека будут ссылаться на разные типы, нарушая бинарную совместимость.

В конечном итоге intmax_t/uintmax_t немного не соответствуют целям, описанным для них в стандарте.

Список источников

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам