Що таке портативний метод, щоб знайти максимальне значення size_t?


74

Я хотів би знати максимальне значення size_t в системі, в якій працює моя програма. Моїм першим інстинктом було використовувати мінус 1, ось так:

Але я здогадуюсь, що є кращий спосіб, або десь визначена константа.


2
Це один дуже розумний трюк. +1!
Mhmmd

Так, те, що ти маєш, чудово (до речі, акторський склад вам не потрібен).
Стівен Канон

2
@Craig: Однією з можливих причин може бути встановлення цього значення як недійсного значення для size_tзмінної типу. Наприклад, std::string::nposвстановлено значення (size_t)-1(принаймні у реалізації MSVC).
Преторіан

1
Хтось може пояснити, що size_t max_size = (size_t)-1;насправді робить і як? Дякую.
Колюня

4
size_tє типом без підпису відповідно до стандарту. Так скажімо, це визначається як 32-бітове значення. -1 представляється як 0xffffffff для підписаного значення з використанням доповнення двох. Однак, якщо ми перекинемо це на size_t, який є непідписаним типом, натомість це максимальне значення. (size_t)(-1)те саме, що і (size_t)(0xffffffff)в 32-розрядної системі. Краще використовувати -1, оскільки це спрацює, якщо він 16-розрядний (0xffff) або 64-розрядний.
Йоаким

Відповіді:


70

Константа маніфесту (макрос) існує в C99 і вона викликається SIZE_MAX. У C89 / 90 такої константи немає.

Однак те, що ви маєте у своєму початковому дописі, - це цілком портативний метод пошуку максимального значення size_t. Гарантована робота з будь-яким типом без підпису.


Дякую, моєму компілятору потрібен привід, або видається попередження про зміну знака під час цілочисельного перетворення.
Юстикул

8
@jamesdlin: Перетворення підписаного в беззнаковий завжди чітко визначено в C. Потрібно дотримуватися правил типової непідписаної модульної арифметики з модулем, рівним найбільшому значенню цільового типу без підпису плюс 1. Отже, у наведеному вище справу ви отримаєте -1 mod (<max-value> + 1), що завжди справедливо <max-value>.
АНТ

6
@jamesdlin: §5.2.4.2.1 гарантує, що -1можна представити як int. §6.3.1.3 гарантує, що він перетворюється на дійсне size_tзначення.
Стівен Канон

1
@jamesdlin: ще один спосіб побачити, що size_tце тип без підпису, тому всі значення є дійсними. Це не може бути поданням пастки, оскільки такої пастки немає.
Йенс Густедт,

1
@jamesdlin: так, нетипізовані типи дійсно простодушні ;-) від " 6.2.6.2 Integer types": If there are N value bits, each bit shall represent a different power of 2 between 1 and 2^N−1..Отже, для цілочисельних типів без підпису насправді не існує сюрпризів.
Йенс Густедт,


5

Як альтернативу бітовим операціям, запропонованим в інших відповідях, ви можете зробити це в C ++


1
std::numeric_limits<size_t>::max()не є constexpr, і це не оптимізовано добре деякими компіляторами, як Clang. GCC, ICC та MSC добре справляються з цим. Його часто краще дотримуватися #define.
jww

3
@jww Там повинна бути constexprверсія max()доступною: en.cppreference.com/w/cpp/types/numeric_limits/max
underscore_d

4

size_t max_size = (size_t)-1;Рішення , запропоноване в ОП, безумовно, кращий до сих пір, але я зробив фігуру з інших, більш заплутаних, способу зробити це. Я публікую це просто для академічної цікавості.


13
Якщо я коли-небудь знайду це в якомусь коді (особливо без коментарів), це зробить мене дуже сварливим. :)
Крейг МакКвін

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.