103

I'd like to know the maximum value of size_t on the system my program is running. My first instinct was to use negative 1, like so:

size_t max_size = (size_t)-1;

But I'm guessing there's a better way, or a constant defined somewhere.

Justicle
  • 14,761
  • 17
  • 70
  • 94
  • 7
    That's one very smart trick you've got there. +1! – Mhmmd Aug 12 '10 at 21:49
  • 4
    Yep, what you have is fine (you don't need the cast, by the way). – Stephen Canon Aug 12 '10 at 21:56
  • Out of curiosity, why would you like to know this? – Craig McQueen Aug 13 '10 at 02:31
  • 2
    @Craig: One possible reason could be to set that as an invalid value for a `size_t` type variable. For instance, `std::string::npos` is set to `(size_t)-1` (at least in the MSVC implementation). – Praetorian Aug 13 '10 at 03:09
  • The way you have done is the best way. `SIZE_MAX` is also available on C99 but not older versions of the standard. – R.. GitHub STOP HELPING ICE Aug 13 '10 at 06:47
  • @Craig: Pretty much what @Praetorian said. – Justicle Aug 16 '10 at 00:36
  • 3
    Can someone explain, what `size_t max_size = (size_t)-1;` actually does and how? Thank you. – Kolyunya Jul 01 '13 at 12:13
  • 6
    `size_t` is an unsigned type according to the standard. So say it's defined as a 32-bit value. A -1 is represented as 0xffffffff for a signed value using two's complement. However if we cast this to size_t which is an unsigned type, it is the max value instead. `(size_t)(-1)` is the same as `(size_t)(0xffffffff)` on a 32-bit system. It is better to use the -1 since that will work if it's 16-bit (0xffff) or 64-bit as well. – Joakim Feb 15 '14 at 12:24
  • @Craig Another reason under Posix is converting safely from `off_t` to `size_t`. `off_t` is aka `long long` for me right now (Xcode 5 on Mavericks) whereas `size_t` is aka `unsigned long` - so I need to range check the `off_t` file size I get back from `fstat` before I can safely cast it to `size_t` and pass it into `mmap`. – Paul Delhanty Apr 20 '14 at 05:12

5 Answers5

85

A manifest constant (a macro) exists in C99 and it is called SIZE_MAX. There's no such constant in C89/90 though.

However, what you have in your original post is a perfectly portable method of finding the maximum value of size_t. It is guaranteed to work with any unsigned type.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    Thank you, my compiler needs the cast, or a warning is issued about change of sign during an integer conversion. – Justicle Aug 12 '10 at 22:03
  • Is it true that's perfectly portable? What prevents it from being a trap representation? – jamesdlin Aug 12 '10 at 22:18
  • 9
    @jamesdlin: The signed-to-unsigned conversion is always well-defined in C. It is required to follow the rules of typical unsigned modulo arithmetics with modulo equal to the largest value of the target unsigned type plus 1. So, in the above case you will get `-1 mod ( + 1)`, which is always just ``. – AnT stands with Russia Aug 12 '10 at 22:24
  • 8
    @jamesdlin: §5.2.4.2.1 guarantees that `-1` is representable as an `int`. §6.3.1.3 guarantees that it converts to a valid `size_t` value. – Stephen Canon Aug 12 '10 at 22:35
  • 1
    @jamesdlin: another way to see that is that `size_t` is an unsigned type, so all values are valid. This can't be a trap representation since there is no such trap. – Jens Gustedt Aug 13 '10 at 06:36
  • @Jens Gustedt: That doesn't help, because I don't think it's necessarily true that all N-bit patterns are necessarily valid for an N-bit unsigned type. However, I do find Stephen's point about §6.3.1.3 compelling since it specifically refers to "the maximal value that can be represented in the new type", which is independent of bit allocation. – jamesdlin Aug 13 '10 at 09:27
  • 1
    @jamesdlin: yes it does, unsigned types are really simple minded ;-) from "`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..` So for unsigned integer types there are really no surprises possible. – Jens Gustedt Aug 13 '10 at 12:45
  • @Jens Gustedt: You conveniently ignored the part of that section that says: "For unsigned integer types, the bits ... shall be divided into two groups: value bits and padding bits...." Your quote specifically refers to *value bits*. – jamesdlin Aug 13 '10 at 18:18
  • @jamesdlin: Yes, but normally you can't create an invalid combination if *padding* bits by doing simple assignment. The danger of producing a trap representation in *padding* bits exists if you "hack" into the object representation through raw memory access, which we are not doing here. – AnT stands with Russia Aug 13 '10 at 18:41
  • @AndreyT: Yeah, I am now in complete agreement that this won't generate a trap representation. My last couple of comments were solely about the claim that there can be no trap representations for unsigned types. – jamesdlin Aug 13 '10 at 18:47
21
#define MAZ_SZ (~(size_t)0)

or SIZE_MAX

nategoose
  • 12,054
  • 27
  • 42
12

As an alternative to bit-operations suggested in the other answers, you could do this in C++

#include <limits>
size_t maxvalue = std::numeric_limits<size_t>::max()
kalmiya
  • 2,988
  • 30
  • 38
  • 1
    `std::numeric_limits::max()` is not a `constexpr`, and it is not optimized well by some compilers, like Clang. GCC, ICC and MSC handle it fine. Its often better to stick with the `#define`. – jww Nov 18 '15 at 10:07
  • 4
    @jww There _should_ be a `constexpr` version of `max()` available: http://en.cppreference.com/w/cpp/types/numeric_limits/max – underscore_d Oct 23 '16 at 18:42
5

The size_t max_size = (size_t)-1; solution suggested by the OP is definitely the best so far, but I did figure out another, more convoluted, way to do this. I'm posting it just for academic curiosity.

#include <limits.h>

size_t max_size = ((((size_t)1 << (CHAR_BIT * sizeof(size_t) - 1)) - 1) << 1) + 1;
Rahul Kadukar
  • 858
  • 3
  • 15
  • 35
Praetorian
  • 106,671
  • 19
  • 240
  • 328
1

If you are assuming at least C++11 compiler then SIZE_MAX should be available to you:

http://en.cppreference.com/w/c/types/limits

Shital Shah
  • 63,284
  • 17
  • 238
  • 185