The Size Puzzle: Why Do int and long Behave Differently on Different Compilers?
\n\nAnyone who has seriously studied C++ has encountered this puzzle sooner or later. You write a simple piece of code:
\n\n#include <iostream>\n\nint main() {\n std::cout << "Size of int: " << sizeof(int) << " bytes\\n";\n std::cout << "Size of long: " << sizeof(long) << " bytes\\n";\n std::cout << "Size of long long: " << sizeof(long long) << " bytes\\n";\n return 0;\n}\n\nYou run it on your laptop — you get 4, 4, 8. You run it on a Linux server — 4, 8, 8. And on an old 16-bit system (yes, they still exist!) — 2, 4, 8. What's the catch? Why does C++, a language renowned for its power and control, allow such uncertainty?
\n\nThe answer is both simple and complex: The C++ standard deliberately leaves the sizes of integer types up to the implementation. This is not a bug, but a feature that allows the language to work on any hardware — from microcontrollers to supercomputers. But for a developer, this means one thing: if you are writing portable code, you cannot rely on specific sizes.
\n\nLet's figure out what the C++ standard (from C++98 to C++23) actually guarantees and how to avoid the trap of platform dependence.
\n\nWhat Does the C++ Standard Guarantee? Minimum Sizes and Hierarchy
\n\nInstead of saying "int is 4 bytes," the standard establishes minimum value ranges and a strict size hierarchy. Here are the key rules from the standard draft (section [basic.fundamental]):
\n\n- \n
- Minimum size of
char: 1 byte (8 bits, although formally a byte in C++ can be larger). \n - Size hierarchy:
sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long). \n - Minimum bits:\n
- \n
short: at least 16 bits. \n int: at least 16 bits. \n long: at least 32 bits. \n long long: at least 64 bits (added in C++11). \n
\n - Size of
int: The standard recommends thatinthave a "natural size" for the target architecture (usually 4 bytes on 32/64-bit systems). \n
Note: long can be equal to int (on 32-bit Windows) or long long (on 64-bit Linux). This is perfectly legal!
Practical Example: Check on Your System
\n\nRun this code and compare the results with colleagues on different OSes:
\n\n#include <iostream>\n#include <climits> // for INT_MAX, LONG_MAX, etc.\n\nint main() {\n std::cout << "Sizes in bytes:\\n";\n std::cout << "short: " << sizeof(short) << "\\n";\n std::cout << "int: " << sizeof(int) << "\\n";\n std::cout << "long: " << sizeof(long) << "\\n";\n std::cout << "long long: " << sizeof(long long) << "\\n\\n";\n\n std::cout << "Maximum values:\\n";\n std::cout << "INT_MAX: " << INT_MAX << "\\n";\n std::cout << "LONG_MAX: " << LONG_MAX << "\\n";\n std::cout << "LLONG_MAX: " << LLONG_MAX << "\\n";\n return 0;\n}\n\nYou will see that on Windows (MSVC) long is often 4 bytes, while on Linux (GCC/Clang) it is 8 bytes. This is a classic source of bugs when porting code between platforms.
Why Doesn't the Standard Fix the Sizes? Historical Context
\n\nImagine the 1970s. Processors were 8-bit, 16-bit, and 32-bit ones were just emerging. The creators of C (and