Why are C++ int and long types both 4 bytes?
The only things guaranteed about integer types are:
sizeof(char) == 1
sizeof(char) <= sizeof(short)
sizeof(short) <= sizeof(int)
sizeof(int) <= sizeof(long)
sizeof(long) <= sizeof(long long)
sizeof(char) * CHAR_BIT >= 8
sizeof(short) * CHAR_BIT >= 16
sizeof(int) * CHAR_BIT >= 16
sizeof(long) * CHAR_BIT >= 32
sizeof(long long) * CHAR_BIT >= 64
The other things are implementation defined. Thanks to (4), both long
and int
can have the same size, but it must be at least 32 bits (thanks to (9)).
Can I assume the size of long int is always 4 bytes?
The standards say nothing regarding the exact size of any integer types aside from char
. Typically, long
is 32-bit on 32-bit systems and 64-bit on 64-bit systems.
The standard does however specify a minimum size. From section 5.2.4.2.1 of the C Standard:
1 The values given below shall be replaced by constant expressions
suitable for use in#if
preprocessing directives. Moreover,
except forCHAR_BIT
andMB_LEN_MAX
, the following shall be
replaced by expressions that have the same type as would an
expression that is an object of the corresponding type converted
according to the integer promotions. Their implementation-defined
values shall be equal or greater in magnitude (absolute value) to
those shown, with the same sign....
minimum value for an object of type
long int
LONG_MIN
-2147483647 // −(2^31−1)maximum value for an object of type
long int
LONG_MAX
+2147483647 // 2^31−1
This says that a long int
must be a minimum of 32 bits, but may be larger. On a machine where CHAR_BIT
is 8, this gives a minimum byte size of 4. However on machine with e.g. CHAR_BIT
equal to 16, a long int
could be 2 bytes long.
Here's a real-world example. For the following code:
#include <stdio.h>
int main ()
{
printf("sizeof(long) = %zu\n", sizeof(long));
return 0;
}
Output on Debian 7 i686:
sizeof(long) = 4
Output on CentOS 7 x64:
sizeof(long) = 8
So no, you can't make any assumptions on size. If you need a type of a specific size, you can use the types defined in stdint.h
. It defines the following types:
int8_t
: signed 8-bituint8_t
: unsigned 8-bitint16_t
: signed 16-bituint16_t
: unsigned 16-bitint32_t
: signed 32-bituint32_t
: unsigned 32-bitint64_t
: signed 64-bituint64_t
: unsigned 64-bit
The stdint.h
header is described in section 7.20 of the standard, with exact width types in section 7.20.1.1. The standard states that these typedefs are optional, but they exist on most implementations.
Why is int the same size as long in C?
According to this:
The standard mandates that int
is at least 16 bit, and long
is at least 32 bit. So depending on the implementation, it's possible that they're the same size (they could both be 32 bit), or they could be of different sizes. This means that the same program compiled for two different environments may behave differently if it makes assumptions about the size of those data types.
why wouldn't there be an overflow? Is it adjusted during runtime when
there is a need for larger numbers?
If for instance you add two integers and store the result in a long
, there could indeed be overflow if the long
has the same size as the int
. That's the problem with those types not having a guaranteed size. If you need such a guarantee, use types like int32_t
and int64_t
instead, those are guaranteed to be 32 respectively 64 bit.
Why does long integer take more than 4 bytes on some systems?
The extra bytes aren't a waste of space. A larger range is quite useful. The standard specifies minimum ranges, not the precise range itself; there's nothing wrong with having wider types.
When the standard originally specified an int
should be at least 16 bits, common processors had registers no larger than that. Representing a long
took two registers and special operations!
But then 32 bits became the norm, and now int
s are 32 bits everywhere and long
s are 64. Nowadays most processors have 64-bit instructions, and a long
can often be stored in a single register.
Why long int has same size as int? Does this modifier works at all?
The reason that MS choose to makelong
32 bits even on a 64-bit system is that the existing Windows API, for historical reasons use a mixture of int
and long
for similar things, and the expectation is that this is s 32-bit value (some of this goes back to times when Windows was a 16-bit system). So to make the conversion of old code to the new 64-bit architecture, they choose to keep long
at 32 bits, so that applications mixing int
and long
in various places would still compile.
There is nothing in the C++ standard that dictates that a long
should be bigger than int
(it certainly isn't on most 32-bit systems). All the standard says is that the size of short
<= int
<= long
- and that short
is at least 16 bits, if memory serves [not necessarily expressed as "should be at least 16 bits", I think it mentions the range of values].
Related Topics
What Happens to the Memory Allocated by 'New' If the Constructor Throws
How Concatenate a String and a Const Char
Fastest Timing Resolution System
Why Do I Need to Include Both the iOStream and Fstream Headers to Open a File
Disable Sleep Mode in Windows Mobile 6
C++ "Hello World" Boost Tee Example Program
Should I Include Stddef.H or Cstddef for Size_T
Opencv's Canny Edge Detection in C++
Does It Make Sense for Unary Operators to Be Associative
C++ Initializing Non-Static Member Array
Win32 C/C++ Load Image from Memory Buffer
Advantages of Using Initializer List
Sorting a List of a Custom Type
Debug Assertion Failed! Expression: _Block_Type_Is_Valid
Is Visual Studio 2013 Optimizing Correctly in the Presence of /Opt:Icf