47

In C99, I include stdint.h and that gives me UINT32_MAX as well as uint32_t data type. However, in C++ the UINT32_MAX gets defined out. I can define __STDC_LIMIT_MACROS before including stdint.h, but this does not work if someone is including my header after already including stdint.h themselves.

So in C++, what is the standard way of finding out the maximum value representable in a uint32_t?

hmofrad
  • 1,784
  • 2
  • 22
  • 28
kdt
  • 27,905
  • 33
  • 92
  • 139

6 Answers6

72

Not sure about uint32_t, but for fundamental types (bool, char, signed char, unsigned char, wchar_t, short, unsigned short, int, unsigned int, long, unsigned long, float, double and long double) you can use the numeric_limits templates via #include <limits>.

cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;

If uint32_t is a #define of one of the above than this code should work out of the box

cout << "Maximum value for uint32_t: " << numeric_limits<uint32_t>::max() << endl;
hmofrad
  • 1,784
  • 2
  • 22
  • 28
Glen
  • 21,816
  • 3
  • 61
  • 76
  • 4
    or if `uint32_t` is a `typedef` of one of the above? – Craig McQueen Jun 11 '13 at 01:56
  • 1
    I sure hope it's a typedef. If your tools use a `#define` for that, I question their quality. – John Jun 11 '13 at 02:18
  • 2
    In order to avoid numeric_limits::min(), numeric_limits::max() from being confused with std::min() and std::max() I had to enclose it in parentheses like this: (std::numeric_limits::max)(); – o'aoughrouer Nov 07 '13 at 16:20
32

std::numeric_limits<T>::max() defines the maximum value for type T.

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
24

Well, uint32_t will always be 32 bit, and always be unsigned, so you can safely define it manually:

#define UINT32_MAX  (0xffffffff)

You can also do

#define UINT32_MAX  ((uint32_t)-1)
Lior Kogan
  • 19,919
  • 6
  • 53
  • 85
  • 45
    We don't need to resort to that when we have perfectly valid standard C++ constructs that use only 3 times as many characters. – John Jun 11 '13 at 02:19
  • 1
    @John: This is perfectly standard and portable as well. – Ben Voigt Nov 06 '13 at 23:17
  • And the standard libraries might not always be available - for kernel module code e.g. ... – mmtauqir Dec 08 '14 at 07:09
  • 1
    I'd consider this only a fall back solution if neither of , nor are available. But then, yes... – Aconcagua Apr 17 '18 at 15:45
  • @BenVoigt I think John was being sarcastic... – 71GA Apr 18 '23 at 06:16
  • 1
    @71GA: Yes, but also making a claim that C++ required you to do it a longer way to be portable / standard-compliant. Which isn't true. The C++ constructs he speak of allow you to use the limits in template code with type parameters, which C++ macros can never do. – Ben Voigt Apr 18 '23 at 14:41
3

I can't comment so here is my input on Glen vs Lior Kogan's answer.

If you are using static variables you will run into the problem that if you assign a constant value inside a class to numeric_limits::max() that value will be in fact set to zero because of the order of initialization (see this post zero initialization and static initialization of local scope static variable)

So in that case it will only work by using Lior Kogan's answer.

// This looks cleaner, less error prone and easier to read than the other suggested by Lior Kogan
#define UINT32_MAX  ((uint32_t)-1)
Community
  • 1
  • 1
Robert Rodriguez
  • 181
  • 1
  • 12
1

You may be able to eliminate the #include order problems by changing your build process to define the __STDC_LIMIT_MACROS symbol on the compiler command line instead:

cxx -D__STDC_LIMIT_MACROS ...

Of course, you would still have trouble if a header #undefs this symbol.

Also, the authors of the standard library implementation that you are using might not have intended for users to set that particular symbol; there might be a compiler flag or a different symbol that users are intended to use to enable C99 types in C++.

bk1e
  • 23,871
  • 6
  • 54
  • 65
0

The maximum value for any unsigned integer type T is T(~T(0)).

Boann
  • 48,794
  • 16
  • 117
  • 146