I hear this question frequently. On the surface, it sounds straightforward. Of course, the answer isn’t going to be one fixed value, at least not across all three languages. And it isn’t always going to be the same even in one language.
In both C and C++, the actual number of bytes occupied by an int, and therefore the range of values it can represent, varies from one compiler implementation to another. On the other hand, in C#, int is just shorthand for the data type Int32, which is always four bytes (32 bits) wide, and therefore always has the same range of values.
The int in C and C++
Let’s begin with C and C++ first. Contrary to popular belief (and contrary to many books, websites, and instructors), an int does not always match the “natural word size” of your hardware. Compiler implementations are free to choose any int size that meets the minimum requirements of the standards, and they often choose a size that is unrelated to the word size of the target CPU or microcontroller on which the code will run.
Both language standards set a minimum width of two bytes (16 bits) for a signed int, with a range of –32,768 to +32,767. Some compiler implementations today (e.g., for some microcontroller targets) have a two-byte integer. Many implementations today have a four-byte (32-bit) int, with a range of –2,147,483,648 to +2,147,483,647. Some implementations have an eight-byte (64-bit) int, with a range of –9,223,372,036,854,775,808 to +9,223,372,036,854,775,807. And some have an int data type that occupies even more than eight bytes, with a wider range of representable values.
Likewise, for an unsigned int, the sizes and ranges also vary across C and C++ compiler implementations. A two-byte unsigned int has a range of 0 to 65,535. A four-byte unsigned int has a range of o to 4,294,967,295. An eight-byte unsigned int has a range of 0 to 18,446,744,073,709,551,615. And there is nothing preventing an unsigned int in a particular compiler implementation from occupying even more bytes, with a wider range of values. The number of bytes occupied by an int in a specific compiler implementation is the same as the number of bytes occupied by an unsigned int.
To keep your C and C++ code portable, your code should never assume the size of or range of an int — or any other data type, for that matter. Use the sizeof operator or the numeric limits (discussed below). Or better yet, if you need specific sized integers, make use of the fixed-width integer types int8_t (one byte), int16_t (two bytes), int32_t (four bytes), and int64_t (eight bytes), which have been available in C++ since C++11 (by including the <cstdint> header), and in C since C99 (by including the <stdint.h> header file.
Numeric limits for various data type can be found in C++ by including the <limits> header and using the numeric_limits type. For example, to see the minimum and maximum values in an int for a specific C++ implementation, you could say:
#include <iostream> // for std::cout
#include <limits> // for std::numeric_limits
int main(void)
{
std::cout << "Minimum value of int: " << std::numeric_limits<int>::min() << '\n';
std::cout << "Maximum value of int: " << std::numeric_limits<int>::max() << '\n';
return 0;
}
In C, you can find the numeric limits specified as #define symbols in the <limits.h> header file. For example, to get the min and max values of an int for a C compiler implementation, you could say:
#include <stdio.h> // for printf
#include <limits.h> // for integer limit #defines
int main(void)
{
printf("Minimum value of int: %d\n", INT_MIN);
printf("Maximum value of int: %d\n", INT_MAX);
return 0;
}
The int in C#
Now, let’s get back to C#. By definition, the int data type is always equivalent to the Int32 type. So, in C#, an int is 32 bits or four bytes wide, with a range of values from
–2,147,483,648 to +2,147,483,647. Likewise, the uint data type is a shorthand version of Uint32, so it will always be 32 bits, with a range from 0 to 4,294,967,295. That said, if you need a specific size of integer for some reason, it’s best to document that in the code by explicitly using the data type names: SByte (aka sbyte), Int16 (aka short), Int32 (aka int), or Int64 (aka long).
In C#, you can find the numeric limits of numeric data types using fields provided by each data type. For example, to get the min and max values of an int in C#, you could say:
using System;
public class Class1
{
public static int Main()
{
Console.WriteLine("Minimum value of int: {0}", Int32.MinValue);
Console.WriteLine("Maximum value of int: {0}", Int32.MaxValue);
return 0;
}
}
All three languages, C, C++, and C# have an int data type. But there’s no one numeric answer to the question “what is the maximum value of an int?”