sizeof(long) in 64-bit C++
Because it doesn't have to be. The C++ standard only requires that it is (if memory serves) at least 32 bits wide, and at least as big as int
.
MSVC (and the ABI used by Windows) defines long
to be 32 bits wide, and MingW follows suit because well, the compiler is a lot more useful when it agrees with the host OS
In C, what is the size of a long for a 32-bit machine and for a 64-bit machine?
The size of long
(and the sizes of objects generally) is determined by the C implementation, not the platform programs execute on.
Generally speaking, a C implementation is a compiler plus the libraries and other supporting software needed to run C programs.1 There can be more than one C implementation for a platform. In fact, one compiler can implement multiple C implementations by using different switches to request various configurations.
A general C implementation typically uses sizes for short
, int
, and long
that work well with the target processor model (or models) and give the programmer good choices. However, C implementations can be designed for special purposes, such as supporting older code that was intended for a specific size of long
. Generally speaking, a C compiler can write instructions for whatever size of long
it defines.
The C standard imposes some lower limits on the sizes of objects. The number of bits in a character, CHAR_BIT
, must be at least eight. short
and int
must be capable of representing values from −32767 to +32767, and long
must be capable of representing −2147483647 to +2147483647. It also requires that long
be capable of representing all int
values, that int
be capable of representing all short
values, and short
be capable of representing all signed char
values. Other than that, the C standard imposes few requirements. It does not require that int
or long
be a particular size on particular platforms. And operating systems have no say in what happens inside a programming language. An operating system sets requirements for running programs and interfacing with the system, but, inside a program, software can do anything it wants. So a compiler can call 17 bits an int
if it wants, and the operating system has no control over that.
Footnote
1 The C 2011 standard (draft N1570) defines an implementation, in clause 3.12, as a “particular set of software, running in a particular translation environment under particular control options, that performs translation of programs for, and supports execution of functions in, a particular execution environment.”
What should be the sizeof(int) on a 64-bit machine?
Doesn't have to be; "64-bit machine" can mean many things, but typically means that the CPU has registers that big. The sizeof a type is determined by the compiler, which doesn't have to have anything to do with the actual hardware (though it typically does); in fact, different compilers on the same machine can have different values for these.
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 does sizeof(long long) return 8?
The C standard does not require long long
to be 16 bytes or to be wider than long
.
In C 2018 5.2.4.2.1 1, the standard requires long long
to be able to represent numbers from −(263−1) to +(263−1). That requires at least 64 bits, so a long long
must be at least 8 8-bit bytes (or, for example, 4 16-bit bytes). It is optional for a C implementation to make long long
wider and support a larger range.
In 6.3.1.1 1, the standard requires the rank of long long
(also known as long long int
) to be greater than the rank of long
. Due to the definition of “rank,” this means long long
must have at least as much precision as long
. (The precision of an integer type is the number of bits used to represent the value, not including the sign bit.) The standard does not require long long
to have more precision than long
; it can be equal.
Related Topics
Both Asterisk and Ampersand in a Parameter
Variable or Field Declared Void
Accessing Static Member Through Invalid Pointer: Guaranteed to "Work"
Efficient Multiply/Divide of Two 128-Bit Integers on X86 (No 64-Bit)
Brace Initialization for Inherited Pod
Referencing Memory Operands in .Intel_Syntax Gnu C Inline Assembly
C++ Expression Must Have a Constant Value
What Is a Good Random Number Generator for a Game
Creating JSON Arrays in Boost Using Property Trees
Addition of Two Pointers in C or C++ Not Supported. Why
Pointer Array and Sizeof Confusion
Differencebetween String::At and String::Operator[]
When Should I Use the Keyword "Typename" When Using Templates